10/25/2006

Le défi de la journée




Pré-scriptum: Si les lettres SQL sonnent pour vous comme la sureté du québec à laval veuillez ignorer ce billet.

Voici un petit défi pour me montrer qui est le vrai geek parmis vous, celui qui trouve le meilleur query va gagner la chance d'apprendre un thérible secret à propos du blogton. Bon si ce prix la vous intéresse pas vous courrez la chance de gagner 10 000 points d'estime de ma pars. Alors voici le défi:

Trouver un query rapide pour afficher la liste des clients qui n'ont pas le service Star lobotomie. Mon Sql est rouillé (et j'ai l'impression qui va revenir assez vite dans les prochains mois!)

Je suis sûr qu'il existe une façon plus éfficace de faire ce query que mes deux exemples plus bas.

Voici le terrain de jeux simplifié:

La table client contient les clients (Ah oui?)

TABLE CLIENT
CLI_ID NOM
---------------
1 BOB
2 BOBETTE
[...]


La table souscription qui contient pleins de services que le client possède


TABLE SOUSCRIPTION
CLI_ID SRV_ID LIGNE SRV_DESC
----------------------------------------------
1 1 1 Poste de cul
1 2 2 Poste de merde
1 294 3 P0rn illimité
1 452 4 Accès internet peewee
2 1 1 Poste de cul
2 2 2 Poste de merde
2 294 3 P0rn illimité
2 903 4 Star lobotomie
[...]

Notez qu'il n'y a pas d'index sur SRV_ID (criss) seulement sur CLI_ID et LIGNE (?!)


Mon premier query relativement simple pour ma tête mais plustôt rushant pour la machine:


SELECT CLI_ID FROM CLIENT
WHERE CLI_ID NOT IN
(SELECT CLI_ID FROM SOUSCRIPTION WHERE SRV_ID = 903)


Mon deuxième essais avec plus de sparage:

SELECT C.NO_CLIENT
FROM CLIENT C
WHERE (SELECT COUNT(*)
FROM SOUSCRIPTION S
WHERE S.NO_CLIENT = C.NO_CLIENT
AND S.ID_SRV = '903') <= 0


PS: Je vous rapelle qu'une simple exclusion <> 903 va quand même retourner des clients si celui-ci possède un autre service que le 903...

PPS: Bien que mes deux exemples semble fonctionner ajouter des millions de clients et pas mal plus de millions de souscriptions et vous comprendrez que ça devient long en SVP. (Et la je parle d'une bd de test bien sûr)

6 commentaires:

Anonyme a dit...

SELECT SOUSCRIPTION.CLI_ID
FROM SOUSCRIPTION
RIGHT JOIN CLIENT
ON CLIENT.CLI_ID = SOUSCRIPTION.CLI_ID
WHERE SOUSCRIPTION.CLI_ID != 903

Mathieu a dit...

Est-ce qu'ya des règles d'affaire du genre "QQN ne peut pas avoir seulement une ligne avec le service STAR" ? C'est ptête un truc pour réduire le nombre d'occurence dans une recherche sur une colonne pas indexée...

Le détaché a dit...

Anonymous: Tel que spécifié il y'a dans cette table plusieurs services pour le même client. Donc ce query va fonctionné seulement pour les clients qui ont seulement un service qui est le 903, hors dans la totalité des cas le client à d'autres services ce qui fait en sorte que le client est ajouter au résultat par ces services. Mais bon regarde le "dump" de données que j'ai crée tu va voir que le client 2 sort quand même dans la liste alors qu'il ne devrait pas y être.


Mathieu: bah tout ce qui peut réduire les occurences on été enlevé pour simplifier l'exemple mais son présent dans mon query original.

Dan a dit...

Ouin, ben je regarde ca pis jarrive pas a battre ta 2eme requete. Le manque d'index sur srv fait tout casser...

Me semble que ca serait logique vite vu de meme quil y en ait un sur srv, mais bon... au moins ta pas de "clet" comme primary key. :D

Sorry si je suis pas plus d'aide!

Le détaché a dit...

Pas de probleme, j'était peut être pas trop dans le champ finalement, Merci à tous

Anonyme a dit...

C'est le temps pour un peu d'humour de g33k !!

SQL> select count(*) from developer_brain;
select count(*) from developer_brain
*
ERROR at line 1:
ORA-00942: table or view does not exist

OMG je suis crampé!! J'ai mouillé mes bobettes blanches...