我有一套信用卡交易的MySQL数据集。
create table trans (
card_id int,
amount int
);
insert into trans values (1, 1);
insert into trans values (2, 1);
insert into trans values (3, 1);
insert into trans values (4, 1);
insert into trans values (5, 1);
insert into trans values (5, 1);
insert into trans values (6, 1);
insert into trans values (6, 1);
insert into trans values (7, 1);
insert into trans values (7, 1);
insert into trans values (8, 1);
insert into trans values (8, 1);
insert into trans values (8, 1);
insert into trans values (9, 1);
insert into trans values (9, 1);
insert into trans values (9, 1);
insert into trans values (10, 1);
insert into trans values (10, 1);
insert into trans values (10, 1);
insert into trans values (10, 1);
我想知道:
1. how many cards were used to make at least 1 transaction
2. how many cards were used to make at least 5 transactions
3. how many cards were used to make at least 10 transactions
4. how many cards were used to make at least 20 transactions
etc...
因为组重叠,所以看起来条件聚合是一种更好的方法:
select sum(cnt >= 1) as trans_1,
sum(cnt >= 5) as trans_5,
sum(cnt >= 10) as trans_10,
sum(cnt >= 20) as trans_20
from (select card_id, count(*) as cnt
from trans
group by card_id
) d;
问题是上面会在列中生成结果集,但我试图在行中生成结果集。
MySQL将列转换为行的传统方式是重复使用表联合中的select sum()序列,但在这种情况下,基本数据是派生表,因此该方法似乎不起作用。有关如何将列翻转到行的任何想法吗?
答案 0 :(得分:2)
您可以通过在计算后旋转行或在单独的行上进行计算来执行此操作。第一个应该有更好的表现:
select x.which,
(case when x.n = 1 then trans_1
when x.n = 2 then trans_5
when x.n = 3 then trans_10
when x.n = 4 then trans_20
end) as numtransactions
from (select sum(cnt >= 1) as trans_1,
sum(cnt >= 5) as trans_5,
sum(cnt >= 10) as trans_10,
sum(cnt >= 20) as trans_20
from (select card_id, count(*) as cnt
from trans
group by card_id
) d
) d join
(select 1 as n, '1 or more' as which union all
select 2, '5 or more' union all
select 3, '10 or more' union all
select 4, '20 or more'
) x
order by x.n;
答案 1 :(得分:0)
这是一个简单的答案,但它确实有效。它的优化程度稍差,因为查询需要多次执行才能进行分组和计数。
select sum(cnt >= 1) as trans_1
from (select card_id, count(*) as cnt
from trans
group by card_id
) d
UNION ALL
select sum(cnt >= 2) as trans_2
from (select card_id, count(*) as cnt
from trans
group by card_id
) d
UNION ALL
select sum(cnt >= 3) as trans_10
from (select card_id, count(*) as cnt
from trans
group by card_id
) d
UNION ALL
select sum(cnt >= 4) as trans_20
from (select card_id, count(*) as cnt
from trans
group by card_id
) d;