SQL 查询:将行转换为列
SQL query : transform rows to columns
这是我的 table 的示例。
我需要执行一个查询,以显示那些在两个月(11 或 12)之一或两个月中费用为 0 的 ID。
所以在示例中,我需要显示 ID 1、3、4 而不是 2,如下面的屏幕截图所示。
我试过下面的查询:
SELECT
t1.id, t1.month, t1.fee, t2.id, t2.month, t2.fee
FROM
table t1, table t2
WHERE t1.id = t2.id
AND t1.month = '11'
AND t2.month = '12'
AND (t1.fee = 0 OR t2.fee = 0);
但是对于这个查询,我只看到 ID 1,3 而不是 ID 4。我猜这是因为 t1.id = t2.id
但不知道该怎么做。
你需要条件聚合
select id,month,max(case when month=11 then fee end) fee11,
max(case when month=12 then fee end) as fee12
from (
select * from table t1
where t1.id in ( select id from table where fee=0)
) a group by id,month
您可以使用条件聚合。在 Postgres 中,这可以使用 filter
语法:
SELECT t.id,
11 as month,
MAX(t.fee) FILTER (WHERE t.month = 11) as fee_11,
12 as month,
MAX(t.fee) FILTER (WHERE t.month = 12) as fee_12
FROM t
GROUP BY t.id
HAVING MAX(t.fee) FILTER (WHERE t.month = 11) = 0 OR
MAX(t.fee) FILTER (WHERE t.month = 12) = 0;
注意:两个月份的列是多余的。
Sql ansi 兼容查询
SELECT id,
MAX(CASE WHEN MONTH = 11 THEN MONTH ELSE NULL END) AS month11,
MAX(CASE WHEN MONTH = 11 THEN fee ELSE NULL END) AS fee11,
MAX(CASE WHEN MONTH = 12 THEN MONTH ELSE NULL END) AS month12,
MAX(CASE WHEN MONTH = 12 THEN fee ELSE NULL END ) AS fee12
FROM t
GROUP BY id
HAVING ( MAX(CASE WHEN MONTH = 11 THEN fee ELSE NULL END) = 0 OR MAX(CASE WHEN MONTH = 12 THEN fee ELSE NULL END ) = 0 )
ORDER BY id
这是我的 table 的示例。
我需要执行一个查询,以显示那些在两个月(11 或 12)之一或两个月中费用为 0 的 ID。
所以在示例中,我需要显示 ID 1、3、4 而不是 2,如下面的屏幕截图所示。
我试过下面的查询:
SELECT
t1.id, t1.month, t1.fee, t2.id, t2.month, t2.fee
FROM
table t1, table t2
WHERE t1.id = t2.id
AND t1.month = '11'
AND t2.month = '12'
AND (t1.fee = 0 OR t2.fee = 0);
但是对于这个查询,我只看到 ID 1,3 而不是 ID 4。我猜这是因为 t1.id = t2.id
但不知道该怎么做。
你需要条件聚合
select id,month,max(case when month=11 then fee end) fee11,
max(case when month=12 then fee end) as fee12
from (
select * from table t1
where t1.id in ( select id from table where fee=0)
) a group by id,month
您可以使用条件聚合。在 Postgres 中,这可以使用 filter
语法:
SELECT t.id,
11 as month,
MAX(t.fee) FILTER (WHERE t.month = 11) as fee_11,
12 as month,
MAX(t.fee) FILTER (WHERE t.month = 12) as fee_12
FROM t
GROUP BY t.id
HAVING MAX(t.fee) FILTER (WHERE t.month = 11) = 0 OR
MAX(t.fee) FILTER (WHERE t.month = 12) = 0;
注意:两个月份的列是多余的。
Sql ansi 兼容查询
SELECT id,
MAX(CASE WHEN MONTH = 11 THEN MONTH ELSE NULL END) AS month11,
MAX(CASE WHEN MONTH = 11 THEN fee ELSE NULL END) AS fee11,
MAX(CASE WHEN MONTH = 12 THEN MONTH ELSE NULL END) AS month12,
MAX(CASE WHEN MONTH = 12 THEN fee ELSE NULL END ) AS fee12
FROM t
GROUP BY id
HAVING ( MAX(CASE WHEN MONTH = 11 THEN fee ELSE NULL END) = 0 OR MAX(CASE WHEN MONTH = 12 THEN fee ELSE NULL END ) = 0 )
ORDER BY id