SQL - 在一个语句中使用查询结果作为另外两个查询的基础

时间:2009-01-14 21:05:19

标签: sql optimization count nested

我正在进行概率计算。我有一个查询来计算事件发生的总次数。从这些事件中,我想得到子事件发生的次数。获取总事件的查询长度为25行,我不想只复制+粘贴两次。

我想对此查询执行两项操作:计算其中的行数,并计算此查询的查询结果中的行数。现在,我能想到的唯一方法是这样做(用复杂的查询替换@ total @来获取所有行,并且@条件@用不太复杂的条件来自@ total @的行必须匹配子事件):

SELECT (SELECT COUNT(*) FROM (@total@) AS t1 WHERE @conditions@) AS suboccurs, 
       COUNT(*) AS totaloccurs FROM (@total@) as t2

正如您所注意到的,@ total @重复了两次。有没有办法解决?有没有更好的方法来做我想做的事情?

再次强调:@ conditions @取决于@ total @返回的内容(它的确如t1.foo = bar所示)。

一些最后的注释:@ total @本身需要~250ms。这个更复杂的查询需要大约300毫秒,因此postgres可能会进行一些优化。尽管如此,查询看起来非常难看,@ total @字面上粘贴了两次。

4 个答案:

答案 0 :(得分:6)

如果你的sql支持子查询因子分解,那么使用WITH语句重写它是一个选项。它允许子查询多次使用。使用它将它们创建为Oracle中的内联视图或临时表。

这是一个人为的例子。

WITH
x AS
(
    SELECT this
    FROM THERE
    WHERE something is true
),
y AS
(
    SELECT this-other-thing
    FROM somewhereelse
    WHERE something else is true
), 
z AS
(
    select count(*) k
    FROM X
)
SELECT z.k, y.*, x.*
FROM x,y, z
WHERE X.abc = Y.abc

答案 1 :(得分:1)

SELECT COUNT(*) as totaloccurs, COUNT(@conditions@) as suboccurs
FROM (@total@ as t1)

答案 2 :(得分:0)

将重用的子查询放入临时表中,然后从临时表中选择所需的内容。

答案 3 :(得分:0)

@EvilTeach:

我没有看到“with”(可能没有在Sybase中实现:-()。我喜欢它:你需要在一个块中做什么然后消失,甚至比临时表更少残酷。很酷。