Cat*_*lin 3 sql postgresql rolap cube outer-join
当我在带有 OUTER JOIN 的查询上使用 PostgreSQL 的CUBE时,我得到一个额外的全 NULL 行,该行无法与多维数据集自己的“所有内容组合”的全 NULL 结果区分开来。
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);
Run Code Online (Sandbox Code Playgroud)
好的,总共有 7 只宠物:
SELECT SUM(number) FROM pet;
sum
-----
7
(1 row)
Run Code Online (Sandbox Code Playgroud)
现在看看立方体的总行数:
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)
Run Code Online (Sandbox Code Playgroud)
5只宠物?哦,对了,因为无物种宠物不包括在内。我需要一个外部连接。
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)
Run Code Online (Sandbox Code Playgroud)
我的多维数据集有 2 个全空行;第二个是我想要的答案。
我不太明白这里发生了什么:NULL 值用于表示两个不同的事情(“多维数据集已汇总此列的所有值”或“此行在右侧表中没有子项”)。我只是不知道如何解决它。
NULL 值用于表示两种不同的情况(“多维数据集已汇总此列的所有值”或“此行在右侧表中没有子项”)。
为了区分一个 null 和另一个 null,您可以使用grouping(...)函数,请参阅此处的表 9-55:https: //www.postgresql.org/docs/9.6/static/functions-aggregate.html#FUNCTIONS-GROUPING-TABLE
GROUPING(args...)指示哪些参数未包含在当前分组集中的整数位
掩码 分组操作与分组集(请参阅第 7.2.4 节)结合使用以区分结果行。GROUPING 操作的参数实际上并未计算,但它们必须与关联查询级别的 GROUP BY 子句中给出的表达式完全匹配。位的分配最右边的参数是最低有效位;如果相应的表达式包含在生成结果行的分组集合的分组标准中,则每个位为 0,如果没有,则为 1。
Run Code Online (Sandbox Code Playgroud)name | is_adult | sum ------+----------+----- | | 2 | | 7第二个是我想要的答案。
尝试这个:
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)
HAVING grouping(name,is_adult) = 3
name |is_adult |sum |
-----|---------|-----|
| |7 |
Run Code Online (Sandbox Code Playgroud)
另请检查此查询以了解grouping函数的工作原理:
SELECT name, is_adult, SUM(number), grouping(name,is_adult)
FROM pet p
LEFT OUTER JOIN species s ON (p.species_id = s.id)
GROUP BY CUBE (name, is_adult)
name |is_adult |sum |grouping |
-----|---------|----|---------|
cat |false |1 |0 |
cat |true |3 |0 |
cat | |4 |1 |
dog |true |1 |0 |
dog | |1 |1 |
|true |2 |0 |
| |2 |1 |
| |7 |3 |
|false |1 |2 |
|true |6 |2 |
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
581 次 |
| 最近记录: |