【问题标题】:Having GROUP BY multiple values giving me all possible combinations拥有 GROUP BY 多个值给我所有可能的组合
【发布时间】:2014-11-24 17:42:13
【问题描述】:

想象一下下表:

type cond
A    good
A    good
A    bad
B    good
B    bad
C    good
C    bad
D    good
D    bad
E    worse

如果我同时按 typecond 计数和分组,我会得到这个:

count type cond
2     A    good
1     A    bad
1     B    good
1     B    bad
1     C    good
1     C    bad
1     D    good
1     D    bad
1     E    worse

但为了更好地将数据汇总到表格中,我更喜欢这样的结果:

count type cond
2     A    good
1     A    bad
0     A    worse
1     B    good
1     B    bad
0     B    worse
1     C    good
1     C    bad
0     C    worse
1     D    good
1     D    bad
0     D    worse
0     E    good
0     E    bad
1     E    worse

我已经设法将所有现有的types 与所有现有的conds 交叉加入,但我不能再数了。 我还尝试针对所有现有的types 或conds 加入结果,但这也不起作用。

SUM-CASE-WHEN 策略在这里不起作用,因为我想让它动态化,即我不知道会有多少 types 或 conds。

是否有一个简单(甚至复杂)的解决方案来生成分组数据的线性矩阵? (奖励:……或者甚至转置它,即二维矩阵,将一组作为表头?)

【问题讨论】:

  • 您有一个父表,其值为“好”、“坏”、“更糟”吗?
  • @JoeTaras:我没有包含所有可能条件的表,但它可以与SELECT cond FROM table GROUP BY cond动态合成(必要时嵌套)
  • 好吧,关于标准化,最好有一个包含这些值的表。

标签: mysql sql group-by left-join cross-join


【解决方案1】:

试试这个:

SELECT 
  COUNT(c.type) as `count`, a.type, b.cond
FROM (
    SELECT DISTINCT type
    FROM table_name
  ) a
  CROSS JOIN (
    SELECT DISTINCT cond
    FROM table_name
  ) b
  LEFT JOIN
    table_name c ON c.type = a.type AND c.cond = b.cond
GROUP BY a.type, b.cond
ORDER BY a.type, b.cond

测试一下:SQL Fiddle

编辑:

要以一组作为表头的二维矩阵显示结果,您必须在运行查询之前知道组名。查询可以是:

SELECT 
  a.type,
  COUNT(CASE WHEN b.cond = 'good'  THEN c.type ELSE NULL END) as good,
  COUNT(CASE WHEN b.cond = 'bad'   THEN c.type ELSE NULL END) as bad,
  COUNT(CASE WHEN b.cond = 'worse' THEN c.type ELSE NULL END) as worse
FROM (
    SELECT DISTINCT type
    FROM table_name
  ) a
  CROSS JOIN (
    SELECT DISTINCT cond
    FROM table_name
  ) b
  LEFT JOIN
    table_name c ON c.type = a.type AND c.cond = b.cond
GROUP BY a.type
ORDER BY a.type

测试一下:SQL Fiddle

【讨论】:

    【解决方案2】:

    为了更好的数据结构,您必须有一个带有cond anagraph 的表,但是...

    您可以使用两个子查询构建您的笛卡尔积,一个用于所有类型,一个用于所有条件,因此,您在 SELECT 字段上有一个子查询,您可以在其中计算这些对的元素。

    试试这个:

    CREATE TABLE app(type char, cond varchar(10));
    
    INSERT INTO app values
    ('A', 'good'),
    ('A', 'good'),
    ('A', 'bad'),
    ('B', 'good'),
    ('B', 'bad'),
    ('C', 'good'),
    ('C', 'bad'),
    ('D', 'good'),
    ('D', 'bad'),
    ('E', 'worse')
    
    select t1.cond, t2.type, (select count(*) from app a3 where a3.cond = t1.cond 
    and (a3.type = t2.type)) as total
    from 
        (select distinct cond
        from app a1) as t1
    cross join
        (select distinct type
        from app a2) as t2
    order by t2.type, t1.cond
    

    Show SqlFiddle

    【讨论】:

      【解决方案3】:
      select 
          A.type,
          A.cond,
          case
              when B.cnt is null then 0
              else B.cnt
          end
      from
          (select 
              type, cond
          from
              (SELECT distinct
              cond
          from
              package)
          cross join (select distinct
              type
          from
              package)) A
              left join
          (select 
              type, cond, count(*) as cnt
          from
              package
          group by type , cond) B ON A.cond = B.cond and A.type = B.type
      order by type
      

      【讨论】:

      • 有人可以缩进吗我不能
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-12-07
      • 2022-01-08
      • 1970-01-01
      • 2013-11-19
      相关资源
      最近更新 更多