将 MySQL 数据库行合并到列中

Merging MySQL database rows into columns

我有一个结构的数据库,其中 id 和 name 是键

id 姓名 cp 时间
1 abc 1 10
1 abc 2 3
1 abc 3 12
2 xyx 1 12
2 xyx 2 11
2 xyx 2 13

我需要一个查询将其合并到一个新的 table 结构中,其中它的 ID 和名称只有 1 行,结构如下,每列值中都有时间。

id 姓名 cp1 cp2 cp3
1 abc 10 3 12
2 xyz 12 11 13

感谢任何帮助。

GROUP BY 将汇总每个 id 和 name。 GROUP_CONCAT 会给你 cp 的列表。这是一个示例查询。

SELECT id, name, GROUP_CONCAT(cp) as cps
FROM your_table
GROUP BY id, name

您可以加​​入您的 table 3 次:

SELECT   m.id as id,
         m.name as name,
         m1.time as cp1,
         m2.time as cp2,
         m3.time as cp3
FROM mytable m            -- This is the base table
LEFT JOIN mytable m1 ON   -- This is a join to take cp1 if present
          m.id = m1.id
          AND m.name = m1.name
          AND m1.cp = 1
LEFT JOIN mytable m2 ON   -- This is a join to take cp2 if present
          m.id = m2.id
          AND m.name = m2.name
          AND m2.cp = 2
LEFT JOIN mytable m3 ON   -- This is a join to take cp3 if present
          m.id = m3.id
          AND m.name = m3.name
          AND m3.cp = 3
GROUP BY m.id,
         m.name,
         m1.time,
         m2.time,
         m3.time

它已被加入 3 次以确保如果您有任何 cp1、cp2 或 cp3 null 它都能正常工作。如果您确定 cp1 cp2 cp3 没有行缺失,您可以只保留 2 个内连接(而不是 3 个左连接)。

请注意,此解决方案适用于任何关系数据库,不仅 mysql 因为没有引用数据库的特殊功能,而且仅适用于标准 SQL 连接。

假设您的数据有错别字,第 6 条记录的 cp 应该是 3,那么您可以使用条件聚合:

SELECT  t.id,
        t.name,
        MAX(CASE WHEN cp = 1 THEN t.time END) AS cp1,
        MAX(CASE WHEN cp = 2 THEN t.time END) AS cp2,
        MAX(CASE WHEN cp = 3 THEN t.time END) AS cp3
FROM T AS t
GROUP BY t.id, t.name;

如果保证每个 idnamecp 的组合都有一个记录,那么 MAX 基本上是无关紧要的,因为您正在使用 MAX 只有一行,所以它是确定性的。如果您可能有重复项,那么您可能需要额外的逻辑来确定应返回多个记录中的哪一个,或者您是否要应用不同的聚合(例如 SUM)。

Example on DB Fiddle