【发布时间】:2016-03-11 15:56:59
【问题描述】:
我正在尝试从两个已经存在的表中提取交易详情:
transactions,包含收到的总金额,bills,交易中收到的每张钞票都有一行,并包含钞票的面额。
两者都使用共同的session id 进行索引。 [更正: 只有transactions 表在session id 上被索引。]
我已加入表格并进行了子查询,以计算每笔交易中每张钞票面额的数量(有多少 10、20 等)。我想为每笔交易获取一条记录,所有计数都在同一行。
我做到了这个查询:
SELECT
t.session,
to_char(t.amount::numeric, '"$"9990D99') AS "USD",
(select count(b.denom) where b.denom = '50' ) AS "50",
(select count(b.denom) where b.denom = '20') AS "20",
(select count(b.denom) where b.denom = '10') AS "10",
(select count(b.denom) where b.denom = '5') AS "5",
(select count(b.denom) where b.denom = '1') AS "1"
FROM transactions AS t JOIN bills AS b USING (session)
GROUP BY
t.session, t.amount, b.denom
ORDER BY
t.session,
b.denom ASC;
...它正确地给了我钞票的数量,但每个面额都有一行:
session | USD | 50 | 20 | 10 | 5 | 1
--------------+-----------+----+----+----+---+----
c64af32f1815 | $ 135.00 | | | | 1 |
c64af32f1815 | $ 135.00 | | | 1 | |
c64af32f1815 | $ 135.00 | | 6 | | |
643e096b6542 | $ 175.00 | | | | | 10
643e096b6542 | $ 175.00 | | | | 1 |
643e096b6542 | $ 175.00 | | 8 | | |
ce7d2c647eff | $ 200.00 | 4 | | | |
我想要的是这样,每笔交易一行:
session | USD | 50 | 20 | 10 | 5 | 1
--------------+-----------+----+----+----+---+----
c64af32f1815 | $ 135.00 | | 6 | 1 | 1 |
643e096b6542 | $ 175.00 | | 8 | | 1 | 10
ce7d2c647eff | $ 200.00 | 4 | | | |
我需要了解什么才能修复此查询?
修改后的查询(遵循@erwin 的建议以避免子查询):
SELECT
t.session,
to_char(t.amount::numeric, '"$"9990D99') AS "USD",
COUNT(NULLIF(b.denom = '100', FALSE)) AS "100",
COUNT(NULLIF(b.denom = '50', FALSE)) AS "50",
COUNT(NULLIF(b.denom = '20', FALSE)) AS "20",
COUNT(NULLIF(b.denom = '10', FALSE)) AS "10",
COUNT(NULLIF(b.denom = '5', FALSE)) AS "5",
COUNT(NULLIF(b.denom = '1', FALSE)) AS "1"
FROM transactions AS t JOIN bills AS b USING (session)
GROUP BY
t.session, t.amount, b.denom
ORDER BY
t.session,
b.denom ASC;
此查询仍会为每个聚合(计数)函数调用生成一行输出。
【问题讨论】:
-
谢谢大家的建议。其中两个答案解决了手头的直接问题,并且似乎是类似的解决方案。 @erwin 的建议允许我将子查询层的数量从 2 减少到 1,但是如果没有子查询,我仍然无法实现我想要的。在选择一个作为答案之前,我想更深入地探索这种可能性。而且我仍然想了解为什么结果不是我的预期......为什么每个聚合函数调用都会在输出中生成一个完整的新行(即使我删除了第二级子查询)?
-
表定义应该在问题中 - 理想情况下是完整的
CREATE TABLE脚本。我们需要查看数据类型和约束。还有你的 Postgres 版本。numeric的演员提出了问题。您的示例中存在不一致之处:您说ORDER BY t.session ...,但所需的结果显示了不同的排序顺序。我已经强调过,你不能在你的GROUP BY中包含b.denom,这是剩下的主要问题。 -
这里的上下文是我试图从一个不是我要更改的数据库中提取报告。对查询和输出进行了轻微编辑/简化,以专注于手头的问题——不一致仅由此产生。强制转换为数字是不必要的,并且是复制/粘贴错误。 (感谢您指出这一点。)
-
好的。所有三个答案都给出了我想要的结果。 (我的一些困惑最终是自己造成的。)我选择@erwin's 作为消除子查询的最佳选择。感谢大家的帮助。
标签: sql postgresql aggregate