将 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;
如果保证每个 id
、name
和 cp
的组合都有一个记录,那么 MAX
基本上是无关紧要的,因为您正在使用 MAX
只有一行,所以它是确定性的。如果您可能有重复项,那么您可能需要额外的逻辑来确定应返回多个记录中的哪一个,或者您是否要应用不同的聚合(例如 SUM
)。
我有一个结构的数据库,其中 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;
如果保证每个 id
、name
和 cp
的组合都有一个记录,那么 MAX
基本上是无关紧要的,因为您正在使用 MAX
只有一行,所以它是确定性的。如果您可能有重复项,那么您可能需要额外的逻辑来确定应返回多个记录中的哪一个,或者您是否要应用不同的聚合(例如 SUM
)。