Forum |  HardWare.fr | News | Articles | PC | S'identifier | S'inscrire | Shop Recherche
1469 connectés 

  FORUM HardWare.fr
  Programmation
  SQL/NoSQL

  group by sur un champ contenant des valeurs null sous oracle

 


 Mot :   Pseudo :  
 
Bas de page
Auteur Sujet :

group by sur un champ contenant des valeurs null sous oracle

n°1450833
crashman
Posté le 02-10-2006 à 15:15:41  profilanswer
 

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
mood
Publicité
Posté le 02-10-2006 à 15:15:41  profilanswer
 

n°1450881
ZeBix
edit > preview
Posté le 02-10-2006 à 16:21:55  profilanswer
 

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

n°1450896
crashman
Posté le 02-10-2006 à 16:40:35  profilanswer
 

l'espoir etait pas au rendez-vous hélas ...
merci zebix !
si quelqu'un connait l'équivalent sous oracle ca me serait utile merci
 

n°1450912
ZeBix
edit > preview
Posté le 02-10-2006 à 16:59:59  profilanswer
 

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  
 

n°1450917
crashman
Posté le 02-10-2006 à 17:04:16  profilanswer
 

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

Message cité 2 fois
Message édité par crashman le 02-10-2006 à 19:18:10
n°1450971
Beegee
Posté le 02-10-2006 à 18:01:48  profilanswer
 

Pourquoi comptes-tu 'no_archive' ???
COUNT sur la valeur nulle renvoie 0 ...
 
Fais plutôt :
 

Code :
  1. Select no_archive, count(*)
  2. from matable
  3. group by no_archive;

n°1450998
anapajari
s/travail/glanding on hfr/gs;
Posté le 02-10-2006 à 18:34:49  profilanswer
 

Beegee a écrit :

Pourquoi comptes-tu 'no_archive' ???
COUNT sur la valeur nulle renvoie 0 ...


+1  :jap:  
 

crashman a écrit :

oe exactement !  
les champs null me pose pas mal de pb , meme sur les jointure du type :  
 
select a.*, b* from table1 a , table1 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


 [:roane]  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 [:pingouino] mais ça change rien sur les jointures ...

Message cité 1 fois
Message édité par anapajari le 02-10-2006 à 18:36:30
n°1451037
crashman
Posté le 02-10-2006 à 19:17:25  profilanswer
 

anapajari a écrit :

+1  :jap:  
 
 
 [:roane]  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 [:pingouino] mais ça change rien sur les jointures ...


 
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 !

n°1451046
crashman
Posté le 02-10-2006 à 19:28:57  profilanswer
 

Beegee a écrit :

Pourquoi comptes-tu 'no_archive' ???
COUNT sur la valeur nulle renvoie 0 ...
 
Fais plutôt :
 

Code :
  1. Select no_archive, count(*)
  2. from matable
  3. group by 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


Message édité par crashman le 02-10-2006 à 19:37:18
n°1451190
ZeBix
edit > preview
Posté le 03-10-2006 à 09:40:01  profilanswer
 

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.


Message édité par ZeBix le 03-10-2006 à 09:48:27
mood
Publicité
Posté le 03-10-2006 à 09:40:01  profilanswer
 

n°1451195
Beegee
Posté le 03-10-2006 à 09:46:39  profilanswer
 

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 :
  1. create table test
  2. (champ1 number(9),
  3. champ2 number(9));
  4. insert into test values (1, 1);
  5. insert into test values (null, null);
  6. insert into test values (null, 1);
  7. select count(champ1) from test;
  8. => 1
  9. select count(champ2) from test;
  10. => 2
  11. select count(*) from test;
  12. => 3

n°1451198
ZeBix
edit > preview
Posté le 03-10-2006 à 09:51:59  profilanswer
 

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  :jap:

n°1451207
Beegee
Posté le 03-10-2006 à 09:58:24  profilanswer
 

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 !  :pt1cable:  
Surtout que le plus lisible et le plus logique est bien le count(*).

Message cité 1 fois
Message édité par Beegee le 03-10-2006 à 09:59:27
n°1451210
anapajari
s/travail/glanding on hfr/gs;
Posté le 03-10-2006 à 09:59:21  profilanswer
 

crashman a écrit :

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


 

crashman a écrit :

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 !


[:quardelitre]


Message édité par anapajari le 03-10-2006 à 10:00:23
n°1451223
ZeBix
edit > preview
Posté le 03-10-2006 à 10:07:57  profilanswer
 

Beegee a écrit :

Je cite une des bibles concernant Oracle, le site AskTom :
 
http://asktom.oracle.com/pls/ask/f [...] 159920245,


 
Merci Tom :  
 

Citation :

select count(*)
from
 all_objects
 
 
call     count       cpu    elapsed       disk      query    current        rows
------- ------  -------- ---------- ---------- ---------- ----------  ----------
Parse        1      0.02       0.02          0          0          0           0
Execute      1      0.00       0.00          0          0          0           0
Fetch        2      5.56       5.56          0     234998          4           1
------- ------  -------- ---------- ---------- ---------- ----------  ----------
total        4      5.58       5.58          0     234998          4           1
 
select count(1)
from
 all_objects
 
 
call     count       cpu    elapsed       disk      query    current        rows
------- ------  -------- ---------- ---------- ---------- ----------  ----------
Parse        1      0.02       0.02          0          0          0           0
Execute      1      0.00       0.00          0          0          0           0
Fetch        2      5.46       5.47          0     234998          4           1
------- ------  -------- ---------- ---------- ---------- ----------  ----------
total        4      5.48       5.49          0     234998          4           1


 
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à  :sweat:  

n°1451273
MagicBuzz
Posté le 03-10-2006 à 11:07:23  profilanswer
 

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à ?


Message édité par MagicBuzz le 03-10-2006 à 11:08:06
n°1451290
Beegee
Posté le 03-10-2006 à 11:30:58  profilanswer
 

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 ...).

Message cité 1 fois
Message édité par Beegee le 03-10-2006 à 11:32:50
n°1451326
MagicBuzz
Posté le 03-10-2006 à 11:52:36  profilanswer
 

de toute façon, rien ne vaut un SUM(1) :D

n°1451451
ZeBix
edit > preview
Posté le 03-10-2006 à 14:22:13  profilanswer
 

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 :
  1. Select no_archive, count(rowid)
  2. from matable
  3. group by no_archive;


 
 :jap:

Message cité 1 fois
Message édité par ZeBix le 03-10-2006 à 14:23:28
n°1451453
MagicBuzz
Posté le 03-10-2006 à 14:24:23  profilanswer
 

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.

n°1451495
crashman
Posté le 03-10-2006 à 15:10:31  profilanswer
 

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 !

n°1451661
Beegee
Posté le 03-10-2006 à 17:36:37  profilanswer
 

ZeBix a écrit :

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 :
  1. Select no_archive, count(rowid)
  2. from matable
  3. group by no_archive;


 
 :jap:


 
Soit dit en passant, COUNT(constante) ou COUNT(rowid) est traduit en COUNT(*) sous Oracle, donc peu importe ;)

mood
Publicité
Posté le   profilanswer
 


Aller à :
Ajouter une réponse
  FORUM HardWare.fr
  Programmation
  SQL/NoSQL

  group by sur un champ contenant des valeurs null sous oracle

 

Sujets relatifs
parcourire un tableau et compter le nombre de valeurs d'une cléEmpêcher de coller dans un champ de formulaire
récupérer les valeurs d'un idQuestion vis a vis des tables sys d'oracle
type date sous oracleévolutions de oracle.jdeveloper.html.picklist depuis JAVA3.2
Changer un paramètre NLS sur Client Oracle (XP)[SQL] Compter le nombre de 'a' dans le texte d'un champ
[Javascript] Accéder à un champ à partir d'une autre pagechamp vide dans un datacombo
Plus de sujets relatifs à : group by sur un champ contenant des valeurs null sous oracle


Copyright © 1997-2022 Hardware.fr SARL (Signaler un contenu illicite / Données personnelles) / Groupe LDLC / Shop HFR