所以,我有一个类似于这个的MySQL表:
|Day | Participant| Score |
+----+------------+-------+
|Mon | Andy | 9 |
|Mon | Betty | 8 |
|Mon | Charlie | 7 |
|Tue | Andy | 6 |
|Tue | Betty | 6 |
|Tue | Charlie | 8 |
|Wed | Andy | 7 |
|Wed | Charlie | 4 |
我想将其输出到:
| Day | Andy | Betty | Charlie |
+-----+------+-------+---------+
| Mon | 9 | 8 | 7 |
| Tue | 6 | 6 | 7 |
| Wed | 7 | null | 4 |
我用PHP解决了这个问题,这就是我想出来的:
使用PHP,每天为每个参与者的分数构建一个子查询,如下所示:
SELECT score FROM TableName WHERE (Day=ref_point AND Participant='Andy')
生成包含所有子查询的主查询,如下所示:
SELECT Day AS ref_point,(/* Sub-query for Andy */) AS Andy,(/* Sub-query for Betty */) AS Betty,(/*Sub-queries for the rest of participants */) AS Others FROM TableName GROUP BY Day
这很好用,但随着参与者数量的增加,查询字符串也会增长。我担心有一天查询变得比PHP的最大字符串长度长。我需要知道如何在MySQL中完全执行此操作。
答案 0 :(得分:3)
SELECT DAY,
MAX(CASE WHEN Participant = 'Andy' THEN Score END) `Andy`,
MAX(CASE WHEN Participant = 'Betty' THEN Score END) `Betty`,
MAX(CASE WHEN Participant = 'Charlie' THEN Score END) `Charlie`
FROM tableName
GROUP BY DAY
如果您的参与者数量未知,则更好的方法是使用Dynamic SQL
,例如
SET @sql = NULL;
SELECT
GROUP_CONCAT(DISTINCT
CONCAT(
'MAX(case when Participant = ''',
Participant,
''' then Score end) AS ',
Participant
)
) INTO @sql
FROM TableName;
SET @sql = CONCAT('SELECT DAY, ', @sql, '
FROM tableName
GROUP BY DAY');
PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
输出
╔═════╦══════╦════════╦═════════╗
║ DAY ║ ANDY ║ BETTY ║ CHARLIE ║
╠═════╬══════╬════════╬═════════╣
║ Mon ║ 9 ║ 8 ║ 7 ║
║ Tue ║ 6 ║ 6 ║ 8 ║
║ Wed ║ 7 ║ (null) ║ 4 ║
╚═════╩══════╩════════╩═════════╝