Différence Oracle/PostgreSQL avec grouping sets

La norme SQL évolue : tirez le meilleur d'un SGBD qui la respecte en écrivant du SQL moderne avec en complément PL/pgSQL, php, java etc.
Répondre
Phil
Administrateur du site
Messages : 249
Enregistré le : mar. 1 sept. 2015 00:38
Localisation : France
Contact :

Différence Oracle/PostgreSQL avec grouping sets

Message par Phil » mar. 26 nov. 2019 11:46

Merci à Guillaume pour sa question :

"Petit problème du jour… (Attention, y’a pas d’urgence à le résoudre car très facilement contournable mais je me dis que ca pourrait peut-être arriver un jour) :

Sous Oracle :
select count(*) from (
select 1 from dual
where 0=1
group by grouping sets(())) tmp;
Résultat : 0.

Sous PostgreSQL :
select count(*) from (
select 1
where 0=1
group by grouping sets(())) tmp;
Résultat : 1.

L’exemple peut paraitre vide de sens mais c’est parce que je l’ai simplifié un maximum.
Le souci est que PostgreSQL renvoie systématiquement la ligne « Total » (dû au grouping set) même si l’ensemble de données est vide.
Savez-vous qui a le bon comportement ?"


Réponse :

Après un échange sur la liste hackers (merci à Pavel Stehule et Tom Lane pour leur participation), nous sommes arrivés à un consensus.

La norme SQL dit :
A <grouping specification> of () (called grand total in the Standard) is equivalent to grouping the entire result Table;

S’il n’y a pas de ligne renvoyée après le FROM et le WHERE, cela doit donner un groupe vide, pas “no data found”.

Exemple :

Code : Tout sélectionner

select count(dummy) from dual where  0 = 1 group by grouping sets(());
et

Code : Tout sélectionner

select count(dummy) from dual where  0 = 1 ;
doivent renvoyer la même chose : UNE ligne 0.

Pour reprendre ton exemple, un select count(*) from (sous-requête 1 ou 2) doit donc renvoyer 1 dans les 2 cas. C’est le cas avec PostgreSQL, pas avec Oracle.

Conclusion : c’est PostgreSQL qui respecte la norme dans ce cas.
Cdlt. Phil - pgphil.ovh

Répondre