【问题标题】:Merging MySQL database rows into columns将 MySQL 数据库行合并到列中
【发布时间】:2021-08-09 15:39:41
【问题描述】:

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

id name cp time
1 abc 1 10
1 abc 2 3
1 abc 3 12
2 xyx 1 12
2 xyx 2 11
2 xyx 2 13

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

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

感谢您的帮助。

【问题讨论】:

  • 您能展示一下您已经提出的查询类型吗?

标签: mysql pivot-table


【解决方案1】:

假设您的数据中有错字,并且第 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

【讨论】:

  • 这就是 SQL 中枢轴的通常构建方式。接受的答案中的 JOIN 变体只应在条件聚合无意义的情况下应用。
【解决方案2】:

您可以加入您的餐桌 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 连接。

【讨论】:

  • 这个解决方案没有错,技术上也是正确的。但它在语法和执行方面都引入了不必要的开销。有关使用条件聚合的通常实现,请参见下文。
【解决方案3】:

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

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

【讨论】:

  • 在此示例中,单个 cps 以逗号分隔列表的形式显示在单个列中,而不是 OP 要求的单独列。
猜你喜欢
  • 1970-01-01
  • 2014-04-27
  • 1970-01-01
  • 2014-11-14
  • 1970-01-01
  • 2018-07-15
  • 1970-01-01
  • 2012-01-28
  • 1970-01-01
相关资源
最近更新 更多