group by sur un champ contenant des valeurs null sous oracle - SQL/NoSQL - Programmation
Marsh Posté le 02-10-2006 à 16:21:55
salut,
essaye GROUP BY ALL no_archive
c'est de la syntaxe Microsoft mais ça devrait marcher sur Oracle, enfin espérons...
http://msdn2.microsoft.com/en-us/library/ms177673.aspx
Marsh Posté le 02-10-2006 à 16:40:35
l'espoir etait pas au rendez-vous hélas ...
merci zebix !
si quelqu'un connait l'équivalent sous oracle ca me serait utile merci
Marsh Posté le 02-10-2006 à 16:59:59
Bon je poserai la question à un dbA oracle de ma boîte demain hihi
Pour être sûr que j'aie bien compris, ce que tu cherches à avoir c'est un output du genre, c'est-ce pas ? :
120 47260
121 46400
122 12630
123 24964
124 31428
125 20839
null 1649877
Marsh Posté le 02-10-2006 à 17:04:16
oe exactement !
les champs null me pose pas mal de pb , meme sur les jointure du type :
select a.*, b* from table1 a , table2 b
where
a.no_archive = b.no_archive
and a.id=b.id
ca me sort pas les enregistrements lorsque ca matche mais que le no_archive est null
si ton bda avais la reponse à ce mystere ca me sauverai pas mal ! merci zebix
Marsh Posté le 02-10-2006 à 18:01:48
Pourquoi comptes-tu 'no_archive' ???
COUNT sur la valeur nulle renvoie 0 ...
Fais plutôt :
Code :
|
Marsh Posté le 02-10-2006 à 18:34:49
Beegee a écrit : Pourquoi comptes-tu 'no_archive' ??? |
+1
crashman a écrit : oe exactement ! |
Apprends les bases du sql ( jointures externes ça te parle pas?) avant de parler de problèmes...
edit: j'avais même pas vu que tu jointais ta table sur elle même mais ça change rien sur les jointures ...
Marsh Posté le 02-10-2006 à 19:17:25
anapajari a écrit : +1 |
salut anapajari, pour de raison de simplification j'ai volontairement mis une requete avec des jointures simples
donc il faut lire :
select a.*, b* from table1 a , table2 b
where
a.no_archive = b.no_archive
and a.id=b.id
je ne veux pas faire une jointure externe !
et je connais les bases de sql merci !
Marsh Posté le 02-10-2006 à 19:28:57
Beegee a écrit : Pourquoi comptes-tu 'no_archive' ???
|
en effet ca ca marche merci !
mais je n'arrive pas a comprendre la logique ... pourquoi les null ne sont pas comptable ?
il me semble que cela fonctionne en tsql ?
merci
Marsh Posté le 03-10-2006 à 09:40:01
La solution en Count(*) fonctionne ici pour l'exemple simplifié ici mais elle est non seulement peu performante si la table réelle a un plus grand nombre de champs (ce que je suppute) mais en plus il suffit qu'un tuple n'ait que des valeurs nulles et le count(*) ne le comptera pas de la même manière qu'il ne comptait pas "no_archive" quand celui-ci est null. Ce n'est pas fiable.
J'ai eu la réponse de mon dbA Oracle au passage : l'erreur de base c'est d'avoir permis les null pour ton champ no_archive. Il vaut mieux prévoir une valeur "0", voire négative si "0" a un sens pour ton champ, qu'un null, lorsque tu as justement besoin de prendre en compte les occurences "vides" ...
Quoi qu'il en soit la solution se trouve dans l'utilisation de la fonction NVL.
Marsh Posté le 03-10-2006 à 09:46:39
Le count(*) n'a pas d'influence particulière sur les performances, c'est une idée préconçue due à des impacts sur les performances de très anciennes versions de certains SGBD.
Maintenant, un petit test rapide montre que count(*) fais bien ce que l'on veut, càd compter les lignes d'une table, quel que soit le contenu :
Code :
|
Marsh Posté le 03-10-2006 à 09:51:59
Beegee a écrit : Le count(*) n'a pas d'influence particulière sur les performances, c'est une idée préconçue due à des impacts sur les performances de très anciennes versions de certains SGBD. |
Source ?
J'ai fait des tests sur MySQL 4.1, qui n'est certes pas le plus récent mais qui est loin d'être une version "très anciennes".
Et sur des croisements de tables volumineuses, la performance va du simple au double, cf. le link dans mon message édité ci-dessus, vers un topic où j'en parle sur hardware.fr
Quant au Count(*) qui ne compte pas les tuples null, au temps pour moi
Marsh Posté le 03-10-2006 à 09:58:24
Je cite une des bibles concernant Oracle, le site AskTom :
http://asktom.oracle.com/pls/ask/f [...] 159920245,
edit: et si mySql n'est toujours pas capable de d'utiliser le même explain plan pour faire un count(*) ou un count(1) ... lol !
Surtout que le plus lisible et le plus logique est bien le count(*).
Marsh Posté le 03-10-2006 à 09:59:21
crashman a écrit : oe exactement ! |
crashman a écrit : salut anapajari, pour de raison de simplification j'ai volontairement mis une requete avec des jointures simples |
Marsh Posté le 03-10-2006 à 10:07:57
Beegee a écrit : Je cite une des bibles concernant Oracle, le site AskTom : |
Merci Tom :
Citation : select count(*) |
Et il ne fait la requête que sur ~230k rows ...
Citation : Surtout que le plus lisible et le plus logique est bien le count(*). |
Je ne vois pas ce qu'il y a de plus lisible et plus logique entre un count(*) et un count(1), ça devient du prosélytisme là
Marsh Posté le 03-10-2006 à 11:07:23
J'ai pas tout suivi.
Hier je bossais pas (Kipour du coup ma boîte fermée).
Et je débarque un peu là.
Vous en êtes où ?
C'est quoi la question exacte en faite ? Faut pas compter les valeurs nulles ?
Pkoi y'a pas une seule proposition : "where champ is not null" alors ?
A l'inverse, s'il faut inclure dans le champ les valeurs nulles "count(isnull(dtc, 0))"
M'enfin c'est un peu trop évident pour être la solution... Vous pouvez reposer la question plus clairement, et dire où vous en êtes là ?
Marsh Posté le 03-10-2006 à 11:30:58
Zebix:
Les explain plans sont les mêmes, les temps d'exécution sont similaires.
En pratique évidemment, les temps d'exécution sont légèrement différents, mais ça tient au fait que certains objets sont mis en cache par la première requête ... dont profite la seconde !
Enfin, COUNT(*) me parait plus logique, ça veut dire "compter les enregistrements". COUNT(expression) veut dire compter les occurrences non nulles de l'expression (donc COUNT(1) veut dire compter le nombre de fois que 1 est non null ...).
MagicBuzz:
L'auteur voulait simplement compter pour chaque no_archive (même null) le nombre de lignes ... il ne savait pas que la fonction COUNT compte les expressions non nulles. Il lui fallait donc utiliser COUNT(*) par exemple.
Ensuite ça a dégénéré sur le mythe entre la différence de perfs entre COUNT(*) et COUNT(1) (sur un SGBD de ce nom ...).
Marsh Posté le 03-10-2006 à 14:22:13
Beegee a écrit : Enfin, COUNT(*) me parait plus logique, ça veut dire "compter les enregistrements". COUNT(expression) veut dire compter les occurrences non nulles de l'expression (donc COUNT(1) veut dire compter le nombre de fois que 1 est non null ...). |
Ok je vois ...
Dernière chose : sur un point théorique, Count(*) en SQL pur , ne compte PAS les tuples nuls, puisque le "*" désigne tous les champs, et si tous les champs sont nuls ben il ne les prend pas.
On a tous oublié de mentionner le champ "rowid", qui existe dans toute table Oracle, caché, et qui identifie de manière unique chaque tuple.
Donc la solution la plus optimale pour le problème de crashman est bien celle de beegee, à un point près c'est la colonne sélectionnée :
Code :
|
Marsh Posté le 03-10-2006 à 14:24:23
sum(1) ça marche aussi bien dans ce cas (le count(1) aussi vous me direz). le rowid ne me semble pas plus intéressant que la constante 1 dans ce cas. après c'est comme chacun sent, puisque le résultat sera le même pour des performances quasi identiques.
Marsh Posté le 03-10-2006 à 15:10:31
Merci tout le monde pour les reponses,au moins j'aurai le choix entre les sum(1) , count(rowid). count(1)
pensait pas que la valeur null puisse poser autant de probleme ...
NVL est mon nouvel ami ... merci a zebix !
Marsh Posté le 03-10-2006 à 17:36:37
ZeBix a écrit : Ok je vois ...
|
Soit dit en passant, COUNT(constante) ou COUNT(rowid) est traduit en COUNT(*) sous Oracle, donc peu importe
Marsh Posté le 02-10-2006 à 15:15:41
Bonjour,
j'ai un petit probleme lorsque je veux faire la requette suivante car elle ne me retourne pas les champs null
Select no_archive, count(no_archive) from matable
group by no_archive;
voila le resultat retourne :
120 47260
121 46400
122 12630
123 24964
124 31428
125 20839
0
or les enregistrements ayant no_archive = null sont les plus nombreux
comment faire? merci
Message édité par crashman le 02-10-2006 à 16:41:29