1

我有一个信用卡交易的 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 中将列转为行的传统方法是重复使用从表联合中选择 sum() 的序列,但在这种情况下,基础数据是派生表,因此该方法在这里似乎不起作用。关于如何将列翻转为行的任何想法?

http://sqlfiddle.com/#!9/0f741/3

4

2 回答 2

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;
于 2015-04-16T19:55:44.963 回答
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;
于 2015-04-16T19:57:23.557 回答