1

所以,我有一个类似于这个的 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 解决了这个问题,这就是我想出的:

  1. 查询每个参与者的姓名。
  2. 使用 PHP,为每个参与者每天的分数构建一个子查询,如下所示:

    SELECT score FROM TableName WHERE (Day=ref_point AND Participant='Andy')
    
  3. 生成包含所有子查询的主查询,如下所示:

    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 中完全做到这一点。

4

1 回答 1

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 ║
╚═════╩══════╩════════╩═════════╝
于 2013-03-22T13:11:51.077 回答