【问题标题】:SQL how to count the number of credit cards that had at least 1,5,10,20 etc transactions in rowsSQL如何计算行中至少有1,5,10,20等交易的信用卡数量
【发布时间】:2015-06-23 10:40:31
【问题描述】:

我有一个信用卡交易的 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

【问题讨论】:

    标签: mysql sql group-by grouping derived-table


    【解决方案1】:

    您可以通过在计算后旋转行或在单独的行上进行计算来做到这一点。第一个应该有更好的性能:

    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;
    

    【讨论】:

      【解决方案2】:

      这是一个简单的答案,但它有效。由于需要多次执行查询来进行分组和计数,所以这不是最优的。

      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-06-19
        • 2015-06-24
        • 2022-11-02
        • 2011-11-08
        • 2017-10-05
        • 2014-11-06
        • 2021-02-27
        • 1970-01-01
        • 2021-04-07
        相关资源
        最近更新 更多