我在数据库中有一个类似的表:
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语句应该是什么?可能是愚蠢的,但我真的无法理清结果。请帮帮我。
答案 0 :(得分:1)
尽管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
Results :
| per | COUNT(desg) | high | low |
|--------------|-------------|------|-----|
| John Smith | 3 | 1 | 2 |
| Mike | 1 | 1 | 0 |
| Peter Parker | 2 | 2 | 0 |
如果要动态创建列,则可以使用动态数据透视。
create dynamic创建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;
答案 1 :(得分:0)
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;
答案 2 :(得分:0)
您似乎想要条件聚合。在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;
请注意,结果数字将不会有前导零。我认为那不是可取的。如果确实需要,可以将数字转换为左侧填充的字符串。