更新:
似乎我没有充分解释自己,以下示例更通用,我原来的问题是在帖子的最后。
我的问题是,当文档说它应该至少给出1时,count(*)在某些行中给出0。作为另一个用户reported,这发生在v9.7和v11.1上。
这是一个MCVE,所以人们可以看到我在说什么。
我用这个创建我的表:
CREATE TABLE TABLE_1
(
X INT NOT NULL PRIMARY KEY
);
CREATE TABLE TABLE_2
(
Y INT NOT NULL
);
INSERT INTO TABLE_1
VALUES (1),
(2),
(3),
(4),
(5);
INSERT INTO TABLE_2
VALUES (1),
(1),
(2);
如果我们现在执行此查询:
SELECT T1.X, COUNT (*) as c1
from TABLE_1 T1 left join TABLE_2 T2 on (T1.X = T2.Y)
group by T1.X;
它给出了预期的结果,因为每个悬挂元组被计数,每行至少有1个c1。
但是如果我们现在用这个改变表并执行一个RUNSTATS(如mao's comment中所述):
ALTER TABLE TABLE_2
ADD CONSTRAINT fk FOREIGN KEY (Y) REFERENCES TABLE_1 ;
RUNSTATS ON TABLE TABLE_1;
现在执行完全相同的查询会给出一个不同的结果,它应该给出相同的结果集:
SELECT T1.X, COUNT (*) as c1
from TABLE_1 T1 left join TABLE_2 T2 on (T1.X = T2.Y)
group by T1.X;
这给悬空元组的c1赋予零,当它应该给1.这是一个问题,这意味着,(至少在我看来),count(*)不像文档所说的那样。
如果没有,请告诉我我犯了哪个错误。
原始邮件:
我到处都看,但我和我的教授都不明白为什么会这样。我有以下查询:
SELECT A.NAME, COUNT(*)
from SCHEMA_1.ACTORS A LEFT JOIN SCHEMA_2.MOVIES M on (M.PROTAGONIST = A.NAME)
GROUP BY A.NAME
其中NAME是ACTORS的主键,PROTAGONIST是引用NAME的外键。此外,这两个表有两种不同的模式。
理论上我想知道演员是电影主角的次数。 我知道正确的做法应该是使用
COUNT(M.PROTAGONIST)
但由于某些原因,即使COUNT(*)为悬空元组而不是1提供0。
更奇怪的是,如果我这样写:
SELECT A.NAME, COUNT(*), AVG(A.AGE)
from SCHEMA_1.ACTORS A LEFT JOIN SCHEMA_2.MOVIES M on (M.PROTAGONIST = A.NAME)
GROUP BY A.NAME
或者这个:
SELECT A.AGE, COUNT(*)
from SCHEMA_1.ACTORS A LEFT JOIN SCHEMA_2.MOVIES M on (M.PROTAGONIST = A.NAME)
GROUP BY A.AGE
一切都按预期工作,结果中的count(*)没有任何零。
知道为什么会这样吗?