OVH Cloud OVH Cloud

question pur SQL

11 réponses
Avatar
Ch.
Bonjour,

j'ai une table qui contient 2 champs
ID_UTIL, ID_FILM

cette table contient 100% des films de chaque utilisateur !

comment sans faire une boucle par utilisateur récupérer seulement les 2/3
des films de chaque utilisateur ?

Merci par avance !

ps: Sous SQL2000

1 réponse

1 2
Avatar
SQLpro [MVP]
Bonjour,

Christophe a écrit :
ok j'ai compris et le tout en une requete alors la je dis bravo t'es un kind
y'a pas à dire !
lequel de tes bouquin j'ai le plus besoin pour pouvoir ecrire des requetes
comme toi ?



le premier est moins complet sur SQL, mais plus détaillé avec un gros
cahpitre de 120 pages avec plus de 200 requêtes exemples de ce genre là...

Il n'existe plus en version papier, mais il est téléchargeable à un prix
moindre :
http://www.numilog.com/fiche_livre.asp?PIDU63

A +



Merci encore et surtout pour les explications !





"SQLpro [MVP]" a écrit dans le message de
news:O%
-- 1) on classe les occurrences

SELECT T1.ID_UTIL, T1.ID_FILM,
COUNT(ALL T2.ID_FILM) AS CLASSEMENT
FROM T_USER_FILM AS T1
INNER JOIN T_USER_FILM AS T2
ON T1.ID_UTIL = T2.ID_UTIL
AND T1.ID_FILM <= T2.ID_FILM
GROUP BY T1.ID_UTIL, T1.ID_FILM
ORDER BY 1, 3

ID_UTIL ID_FILM CLASSEMENT
----------- ----------- -----------
1 102 1
1 101 2
1 100 3

2 206 1
2 205 2
2 204 3
2 203 4
2 202 5
2 201 6

3 301 1

4 402 1
4 401 2


-- 2) on calcule le nombre total

SELECT T1.ID_UTIL, T1.ID_FILM,
COUNT(ALL T2.ID_FILM) AS CLASSEMENT,
(SELECT COUNT(*)
FROM T_USER_FILM
WHERE ID_UTIL = T1.ID_UTIL) AS NOMBRE_TOTAL
FROM T_USER_FILM AS T1
INNER JOIN T_USER_FILM AS T2
ON T1.ID_UTIL = T2.ID_UTIL
AND T1.ID_FILM <= T2.ID_FILM
GROUP BY T1.ID_UTIL, T1.ID_FILM
ORDER BY 1, 3

ID_UTIL ID_FILM CLASSEMENT NOMBRE_TOTAL
----------- ----------- ----------- ------------
1 102 1 3
1 101 2 3
1 100 3 3

2 206 1 6
2 205 2 6
2 204 3 6
2 203 4 6
2 202 5 6
2 201 6 6

3 301 1 1

4 402 1 2
4 401 2 2


-- 3) on calcule des 2/3 du total

SELECT T1.ID_UTIL, T1.ID_FILM,
COUNT(ALL T2.ID_FILM) AS CLASSEMENT,
(SELECT COUNT(*)
FROM T_USER_FILM
WHERE ID_UTIL = T1.ID_UTIL) * 2 / 3 AS NOMBRE_TOTAL
FROM T_USER_FILM AS T1
INNER JOIN T_USER_FILM AS T2
ON T1.ID_UTIL = T2.ID_UTIL
AND T1.ID_FILM <= T2.ID_FILM
GROUP BY T1.ID_UTIL, T1.ID_FILM
ORDER BY 1, 3

ID_UTIL ID_FILM CLASSEMENT NOMBRE_TOTAL
----------- ----------- ----------- ------------
1 102 1 2
1 101 2 2
1 100 3 2

2 206 1 4
2 205 2 4
2 204 3 4
2 203 4 4
2 202 5 4
2 201 6 4

3 301 1 0

4 402 1 1
4 401 2 1


-- 4) on écrème....

SELECT T1.ID_UTIL, T1.ID_FILM,
COUNT(ALL T2.ID_FILM) AS CLASSEMENT,
(SELECT COUNT(*)
FROM T_USER_FILM
WHERE ID_UTIL = T1.ID_UTIL) * 2 / 3 AS NOMBRE_TOTAL
FROM T_USER_FILM AS T1
INNER JOIN T_USER_FILM AS T2
ON T1.ID_UTIL = T2.ID_UTIL
AND T1.ID_FILM <= T2.ID_FILM
GROUP BY T1.ID_UTIL, T1.ID_FILM
HAVING COUNT(ALL T2.ID_FILM) <= (SELECT COUNT(*)
FROM T_USER_FILM
WHERE ID_UTIL = T1.ID_UTIL) * 2 / 3
ORDER BY 1, 3


Si tu veut un calcul plus précis, transtype en flottant :

SELECT T1.ID_UTIL, T1.ID_FILM,
COUNT(ALL T2.ID_FILM) AS CLASSEMENT,
ROUND(CAST((SELECT COUNT(*)
FROM T_USER_FILM
WHERE ID_UTIL = T1.ID_UTIL) AS FLOAT)
* 2.0 / 3.0, 0) AS NOMBRE_TOTAL
FROM T_USER_FILM AS T1
INNER JOIN T_USER_FILM AS T2
ON T1.ID_UTIL = T2.ID_UTIL
AND T1.ID_FILM <= T2.ID_FILM
GROUP BY T1.ID_UTIL, T1.ID_FILM
HAVING COUNT(ALL T2.ID_FILM)
<= ROUND(CAST((SELECT COUNT(*)
FROM T_USER_FILM
WHERE ID_UTIL = T1.ID_UTIL) AS FLOAT) * 2.0 / 3.0, 0)
ORDER BY 1, 3

ID_UTIL ID_FILM CLASSEMENT NOMBRE_TOTAL

----------- ----------- ----------- -------------
1 102 1 2.0
1 101 2 2.0
2 206 1 4.0
2 205 2 4.0
2 204 3 4.0
2 203 4 4.0
3 301 1 1.0
4 402 1 1.0

A +

SQLpro [MVP] a écrit :
Bonjour,

CREATE TABLE T_USER_FILM
(ID_UTIL INT,
ID_FILM INT)


INSERT INTO T_USER_FILM VALUES (1, 100)
INSERT INTO T_USER_FILM VALUES (1, 101)
INSERT INTO T_USER_FILM VALUES (1, 102)
INSERT INTO T_USER_FILM VALUES (2, 201)
INSERT INTO T_USER_FILM VALUES (2, 202)
INSERT INTO T_USER_FILM VALUES (2, 203)
INSERT INTO T_USER_FILM VALUES (2, 204)
INSERT INTO T_USER_FILM VALUES (2, 205)
INSERT INTO T_USER_FILM VALUES (2, 206)
INSERT INTO T_USER_FILM VALUES (3, 301)
INSERT INTO T_USER_FILM VALUES (4, 401)
INSERT INTO T_USER_FILM VALUES (4, 402)

-- solution :

SELECT T1.ID_UTIL, T1.ID_FILM
FROM T_USER_FILM AS T1
INNER JOIN T_USER_FILM AS T2
ON T1.ID_UTIL = T2.ID_UTIL
AND T1.ID_FILM <= T2.ID_FILM
GROUP BY T1.ID_UTIL, T1.ID_FILM
HAVING COUNT(ALL T2.ID_FILM) <= (SELECT COUNT(*)
FROM T_USER_FILM
WHERE ID_UTIL = T1.ID_UTIL) * 2 / 3


Il serait temps de suivre quelques uns de mes cours....

Sur le net (SQLpro) par mes bouquins ou en formation pro...

A +


Ch. a écrit :
Bonjour,

j'ai une table qui contient 2 champs
ID_UTIL, ID_FILM

cette table contient 100% des films de chaque utilisateur !

comment sans faire une boucle par utilisateur récupérer seulement les
2/3 des films de chaque utilisateur ?

Merci par avance !

ps: Sous SQL2000








--
Frédéric BROUARD, MVP SQL Server, expert bases de données et langage SQL
Le site sur le langage SQL et les SGBDR : http://sqlpro.developpez.com
Audit, conseil, expertise, formation, modélisation, tuning, optimisation
********************* http://www.datasapiens.com ***********************








--
Frédéric BROUARD, MVP SQL Server, expert bases de données et langage SQL
Le site sur le langage SQL et les SGBDR : http://sqlpro.developpez.com
Audit, conseil, expertise, formation, modélisation, tuning, optimisation
********************* http://www.datasapiens.com ***********************
1 2