问题描述
我试图理解我正在做的练习的某些部分,但无法理解。
有一部分选择了“T”,按“a”分组,然后重定向到“具有计数(*) 我试过在谷歌上搜索这类东西,看看是否有类似的例子,但所有其他例子都使用常规数字,例如:“有计数(*)
练习是这样的: 我认为有 count(*) 是将分组的每个值与每行中 T3.a 的每个值进行比较,如果所有行都符合条件,则该值将被选中,但我以某种方式得到了不同的结果. 有人可以向我解释这个“具有计数(*) 提前致谢。create table T(a int,b int);
insert into T values(1,2);
insert into T values(1,1);
insert into T values(2,3);
insert into T values(2,4);
insert into T values(3,4);
insert into T values(4,5);
select T3.b,(select count(T5.a)
from T T5
where T5.a = T3.b)
from (select T1.a as a,T2.b as b
from T T1,T T2
where T1.b < T2.a) as T3
where not exists (select T4.a
from T T4
group by T4.a
having count(*) < T3.a);
解决方法
从评论中重复我自己,对于聚合函数,HAVING
就像 WHERE
。您不能在WHERE
中使用聚合函数,例如WHERE SUM(SomeColumn) > 5
,因此您需要在HAVING
中使用它们:HAVING SUM(SomeColumn) > 5
。这将返回组中列 SUM
的 SomeColumn
大于 5 的任何行。
对于您的表达式,HAVING COUNT(*) < T3.a
只会返回 COUNT(*)
的值小于 T3.a
的值的行。
让我们把它分解成不同的部分。
首先是 FROM
from (select T1.a as a,T2.b as b
from T T1,T T2
where T1.b < T2.a) as T3
这使用旧式已弃用的交叉连接语法。可以重写为普通连接:
from (select T1.a as a,T2.b as b
from T T1
join T T2 on T1.b < T2.a
) as T3
如果我们分析它的作用,我们就会意识到它实际上是所谓的三角连接:每一行都自连接到比它低的每一行。这通常在窗口聚合不可用时执行。
WHERE
where not exists (select T4.a
from T T4
group by T4.a
having count(*) < T3.a);
这是一个相关子查询:T3.a
是对外部查询的引用。
这个谓词说的是:对于这个特定的行,子查询中必须没有行。
子查询本身说:取 T
中的所有行,按 a
分组并计数,然后只包括计数小于外部引用 a
的行。
请注意,因为它是一个 EXIST
,所以不使用实际选定的值。我怀疑这可能不是故意的。
SELECT
select T3.b,(select count(T5.a)
from T T5
where T5.a = T3.b)
然后我们从第一个连接中获取 b
,并从所有匹配的 T
行的子查询中获取计数。同样,当窗口聚合不可用时,这很常见。
所以整个事情可以改写如下:
select T2.b,(select count(T5.a)
from T T5
where T5.a = T3.b)
from (
select *,count(*) over (partition by a) as cnt
from T
) T1
join T T2 on T1.b < T2.a
where T1.cnt < T1.a;
您查询中的逻辑有些不太正确,但不知道最初的意图是什么,也没有看到表和列名,我不能说。特别是三角形连接看起来很可疑。