我尝试编写查询以获取具有条件的表的总和。 例如这个表
area | machine | status | qty
1 | machine1 | inprocess | 210
1 | machine2 | pending | 120
1 | machine3 | done | 50
2 | machine1 | inprocess | 30
2 | machine2 | done | 170
我想要的结果是
area | inprocess sum | pending sum | done sum | all sum
1 | 210 | 120 | 50 | 380
2 | 30 | 0 | 170 | 200
我正在考虑有条件的分组,但我似乎无法获得解决此问题所需的解决方案。我试过的是
select distinct
area,
(select sum(qty) from table
where status = 'inprocess'
and area = mainTable.area) as inprocess sum
(select sum(qty) from table
where status = 'pending'
and area = mainTable.area) as pending sum
(select sum(qty) from table
where status = 'done'
and are = mainTable.area) as done sum
from table mainTable
在某一点上,它确实有效,但当我尝试检查我是否获得正确的数量时,我似乎无法将实际值与查询结果相匹配。 (我正在处理更大的数据集,数百万条记录)。我想我真正想要的是一个group by子句,我可以将条件放入其中,因此它只会聚合符合条件的记录。请轻轻的绝地大师
答案 0 :(得分:3)
您可以尝试使用数据透视查询:
SELECT t.area, SUM(t.isum) AS "inprocess sum",
SUM(t.psum) AS "pending sum",
SUM(t.dsum) AS "done sum",
SUM(t.isum) + SUM(t.psum) + SUM(t.dsum) AS "all sum"
FROM
(
SELECT area,
CASE WHEN status = 'inprocess' THEN qty ELSE 0 END AS isum,
CASE WHEN status = 'pending' THEN qty ELSE 0 END AS psum,
CASE WHEN status = 'done' THEN qty ELSE 0 END AS dsum
FROM mainTable
) t
GROUP BY t.area
如果您使用的是Oracle 11g或更高版本,那么您还可以利用内置的PIVOT
功能:
SELECT area, isum_qty AS "inprocess sum", psum_qty AS "pending sum", dsum_qty AS "done sum",
isum_qty + psum_qty + dsum_qty AS "all sum"
FROM
(
SELECT area, status
FROM mainTable
)
PIVOT
(
SUM(qty) AS qty
FOR status IN ('inprocess' AS "isum", 'pending' AS "psum", 'done' AS "dsum")
)
ORDER BY area ASC;
答案 1 :(得分:1)
您应该使用PIVOT查询:
WITH pivot_data AS (
SELECT area,status, qty from table
)
SELECT *
FROM pivot_data
PIVOT (
sum(qty) --<-- pivot_clause
FOR table --<-- pivot_for_clause
IN (FORM Hidden FIELD Name) --<-- pivot_in_clause
);
对于动态IN子句,创建一个表单隐藏字段并将以下查询结果传递给此字段。然后将该字段引用到上述查询的IN子句中。
SELECT LISTAGG(dbms_assert.enquote_literal(status), ', ') WITHIN GROUP (ORDER BY status) status
FROM (Select distinct status from table)