Lorsque j'utilise le CUBE de PostgreSQL sur une requête avec un OUTER JOIN, j'obtiens une ligne supplémentaire NULL qui ne peut pas être distinguée du résultat "tout combiné" tout-NULL du cube .CUBE + jointure externe = ligne NULL supplémentaire
CREATE TABLE species
(id SERIAL PRIMARY KEY,
name TEXT);
CREATE TABLE pet
(species_id INTEGER REFERENCES species(id),
is_adult BOOLEAN,
number INTEGER)
;
INSERT INTO species VALUES
(1, 'cat'), (2, 'dog');
INSERT INTO pet VALUES
(1, true, 3), (1, false, 1), (2, true, 1), (null, true, 2);
OK, donc il y a 7 animaux au total:
SELECT SUM(number) FROM pet;
sum
-----
7
(1 row)
Maintenant, regardez la ligne totale du cube:
SELECT * FROM (
SELECT name, is_adult, SUM(number)
FROM pet p
JOIN species s ON (p.species_id = s.id)
GROUP BY CUBE (name, is_adult)) subq
WHERE name IS NULL
AND is_adult IS NULL;
name | is_adult | sum
------+----------+-----
| | 5
(1 row)
5 animaux? Oh, c'est vrai, parce que les animaux de compagnie sans espèce ne sont pas inclus. J'ai besoin d'une jointure externe.
SELECT * FROM (
SELECT name, is_adult, SUM(number)
FROM pet p
LEFT OUTER JOIN species s ON (p.species_id = s.id)
GROUP BY CUBE (name, is_adult)) subq
WHERE name IS NULL
AND is_adult IS NULL;
name | is_adult | sum
------+----------+-----
| | 2
| | 7
(2 rows)
Mon cube a deux lignes null-nulles; le second est la réponse que je voulais. Je comprends à moitié ce qui se passe ici: les valeurs NULL sont utilisées pour signaler deux choses différentes ("le cube a roulé toutes les valeurs de cette colonne" ou "cette ligne n'a pas d'enfants dans la table de droite") . Je ne sais pas comment le réparer.