Sql 另一个表中的计数尚不存在,无法在何处进行筛选
我得到以下错误: 使用此查询:Sql 另一个表中的计数尚不存在,无法在何处进行筛选,sql,postgresql,join,aggregate-functions,Sql,Postgresql,Join,Aggregate Functions,我得到以下错误: 使用此查询: SELECT d.id, COUNT(1) FILTER (WHERE s.is_primary = True) AS primarycount, COUNT(1) FILTER (WHERE s.is_primary = False) AS nonprimarycount FROM Dino d LEFT JOIN Senator s ON d.id = s.id WHERE nonprimarycount < 10 GROUP BY d.id
SELECT
d.id,
COUNT(1) FILTER (WHERE s.is_primary = True) AS primarycount,
COUNT(1) FILTER (WHERE s.is_primary = False) AS nonprimarycount
FROM Dino d
LEFT JOIN Senator s ON d.id = s.id
WHERE nonprimarycount < 10
GROUP BY d.id
ORDER BY nonprimarycount DESC,
primarycount DESC;
我很清楚我不能这样做,因为我所做的非主要计数还不存在,但我不清楚如何正确地这样做。我只想选择非主要计数少于10的记录,我需要在查询中构造该计数。使用having子句:
我认为Postgres要求您重复该表达式,而不是使用列别名。正如Gordon指出的,您的错误在哪里而不是在哪里
但我建议您将查询改写如下:
SELECT id
, COALESCE(s.primarycount , 0) AS primarycount
, COALESCE(s.nonprimarycount, 0) AS nonprimarycount
FROM dino d
LEFT JOIN (
SELECT id
, count(*) FILTER (WHERE is_primary) AS primarycount
, count(*) FILTER (WHERE is_primary = false) AS nonprimarycount
FROM senator
GROUP BY id
) s USING (id)
WHERE (s.nonprimarycount > 9) IS NOT TRUE
ORDER BY nonprimarycount DESC, primarycount DESC;
应该更快
通常在加入之前聚合要快得多。
由于我们将聚合下推到子查询中,现在可以使用外部选择中的WHERE,而不是have,从而消除错误原因。性能相同,但更简单。
count*更快,在这种情况下是等效的。
is_primary=true是一种嘈杂的说法。
其中s.nonprimarycount>9不为真,与s.nonprimarycount<10或s.nonprimarycount为空的情况相同。
我们现在可以为表中的任何行获取NULL。我默认为0,就像您的原始设置一样。如果您想显示差异,请删除合并并使用ORDER BY。。。DESC NULLS LAST可最后对空值进行排序。
值得注意的是,不合格!输出列名将按顺序工作,即使它与外部选择中的输入列名相同,因为:
如果ORDER BY表达式是与
输出列名和输入列名,ORDER BY将解释
它将作为输出列名。这与我们所做的选择正好相反
分组将在相同的情况下进行。这种不一致是有原因的
与SQL标准兼容
如果我们可以假设每个恐龙在senator中至少有一行,我们可以简化:
选择id
,s.primarycount
,s.nonprimarycount
来自恐龙d
参加
选择id
,count*过滤器,其中_primary作为primarycount
,count*过滤器,其中作为非PrimaryCount的_primary=false
参议员
按id分组
他正在使用身份证
其中s.nonprimary计数<10
按s.nonprimarycount DESC、s.primarycount DESC排序;
现在,计数不能为空。不相关,但是:如果你假设count1'比count*快,那你就错了。这是/慢了/还是没有区别和愚蠢的书写方式?哦,我看这是有争议的
SELECT d.id,
COUNT(1) FILTER (s.is_primary) AS primarycount,
COUNT(1) FILTER (NOT s.is_primary) AS nonprimarycount
FROM Dino d LEFT JOIN
Senator s ON d.id = s.id
GROUP BY d.id
HAVING COUNT(1) FILTER (NOT s.is_primary) < 10
ORDER BY nonprimarycount desc,
primarycount desc;
SELECT id
, COALESCE(s.primarycount , 0) AS primarycount
, COALESCE(s.nonprimarycount, 0) AS nonprimarycount
FROM dino d
LEFT JOIN (
SELECT id
, count(*) FILTER (WHERE is_primary) AS primarycount
, count(*) FILTER (WHERE is_primary = false) AS nonprimarycount
FROM senator
GROUP BY id
) s USING (id)
WHERE (s.nonprimarycount > 9) IS NOT TRUE
ORDER BY nonprimarycount DESC, primarycount DESC;