繁体   English   中英

多组 SQL 数据

[英]Multiple group by SQL data

我在数据库中有一个类似的表:

id    desg        sr       per

1     desg-1      high     John Smith
2     desg-2      high     Peter Parker
3     desg-3      low      John Smith
4     desg-4      high     Mike
5     desg-5      high     Peter Parker
6     desg-6      low      John Smith

现在我想这样整理数据:

Name           count(desg)   high   low

John Smith     03            01     02
Peter Parker   02            00     02
Mike           01            01     00

SQL语句应该是什么? 可能是愚蠢的,但我真的无法理清结果。 请帮帮我。

虽然mysql不支持pivot ,但是你可以尝试使用条件聚合函数

CREATE TABLE T(
   ID INT,
   desg VARCHAR(50),
   sr VARCHAR(50),
   per VARCHAR(50)
);


INSERT INTO T VALUES (1,'desg-1','high','John Smith');
INSERT INTO T VALUES (2,'desg-2','high','Peter Parker');
INSERT INTO T VALUES (3,'desg-3','low','John Smith');
INSERT INTO T VALUES (4,'desg-4','high','Mike');
INSERT INTO T VALUES (5,'desg-5','high','Peter Parker');
INSERT INTO T VALUES (6,'desg-6','low','John Smith');

查询 1

SELECT per,
    COUNT(desg),
    sum(CASE WHEN sr= 'high' THEN 1 else 0 END) high,
    sum(CASE WHEN sr= 'low' THEN 1 else 0  END) low
FROM T
GROUP BY per

结果

|          per | COUNT(desg) | high | low |
|--------------|-------------|------|-----|
|   John Smith |           3 |    1 |   2 |
|         Mike |           1 |    1 |   0 |
| Peter Parker |           2 |    2 |   0 |

如果要动态创建列,可以使用动态数据透视表。

创建动态创建 SQL 执行它。

SET @sql = NULL;
SELECT
  GROUP_CONCAT(DISTINCT
    CONCAT(
      'sum(CASE WHEN sr= ''',
      sr,
      ''' THEN 1 else 0 END) ',
      sr
    )
  ) INTO @sql
FROM T;

SET @sql = CONCAT('SELECT per,
                     COUNT(desg), ', @sql, ' 
                   FROM T
                    GROUP BY per');

PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;

sqlfiddle

FWIW,正如你提到的应用程序代码(PHP),我可能会做这样的事情,并在表示层处理其他所有事情......

SELECT a.per
     , a.sr
     , SUM(COALESCE(b.sr = a.sr,0)) n
  FROM
     ( SELECT DISTINCT x.id, x.per, y.sr FROM my_table x, my_table y ) a
  LEFT
  JOIN my_table b
    ON b.id = a.id
   AND b.sr = a.sr
 GROUP
    BY per
     , sr
 ORDER
    BY per
     , sr;

您似乎想要条件聚合。 这在 MySQL 中很容易做到,使用sum()和布尔表达式:

select per, count(*) as num_desg,
       sum( sr = 'high' ) as num_high,
       sum( sr = 'low' ) as num_low
from t
group by per;

请注意,结果数字不会有前导零。 我不认为这是可取的。 如果确实需要,您可以将数字转换为左填充字符串。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM