1

我想将 count(*) 查询的结果分组到值桶中。我正在 dellstore2 postgresql 示例数据库上对此进行测试。我在下面的查询返回正确的答案,但对表中的每一行执行一次(数千个相同的结果)。我可以通过添加LIMIT 1查询的结尾来解决这个问题,但我想了解为什么我会得到重复项,以防它指出我的方法存在更广泛的问题。查询是:

SELECT
    (SELECT count(*)
        FROM
            orders
        WHERE
            totalamount > 0 AND totalamount <= 100) AS ">0 <= 100",
    (SELECT count(*)
        FROM
            orders
        WHERE
            totalamount > 100 AND totalamount <= 200) AS ">100 <= 200"
...
FROM
    orders;

编辑 Andomar 的回答也让我找到了以下方法(简而言之,改编自 SQL 中的一个示例(O'Reilly))。这让我可以将存储桶放在一列中,每个存储桶/答案配对都有一行。我想我会把它包括在那个用例的任何人身上:

SELECT CASE
        WHEN totalamount IS NULL THEN 'Unknown'
        WHEN totalamount <= 100 THEN 'Not more than 100'
        WHEN totalamount <= 200 THEN 'Not more than 200'
        ELSE 'Over 200'
    END "Bucket",
    COUNT(*) "Number of results"
FROM
    orders
GROUP BY CASE
        WHEN totalamount IS NULL THEN 'Unknown'
        WHEN totalamount <= 100 THEN 'Not more than 100'
        WHEN totalamount <= 200 THEN 'Not more than 200'
        ELSE 'Over 200'
    END
ORDER BY
    MIN(totalamount);
4

2 回答 2

6

您从 中选择每一行orders,然后为每一行评估子查询。

请考虑这种方法:

select  count(case when 0 < totalamount and totalamount <= 100 then 1 end)
            as "<0,100]"
,       count(case when 100 < totalamount and totalamount <= 200 then 1 end)
            as "<100,200]"
from    Orders

这将在单个表扫描中计算两个聚合。

于 2012-03-20T12:13:54.593 回答
3

因为您将它们作为子查询包含在内。从外观上看,两个 count 子查询都是针对表中的每一行执行的orders。如果您from从主查询中省略该部分,您应该只得到一行。

例如,查询

SELECT 'John Doe' FROM orders

为订单表中的每一行返回“John Doe”。

SELECT 'John Doe'

只选择一行。

免责声明:这是 sql server 行为。

于 2012-03-20T12:10:43.580 回答