在 SQL 中合并两行
Posted
技术标签:
【中文标题】在 SQL 中合并两行【英文标题】:Merge two rows in SQL 【发布时间】:2011-02-25 20:01:39 【问题描述】:假设我有一个包含以下信息的表格:
FK | Field1 | Field2
=====================
3 | ABC | *NULL*
3 | *NULL* | DEF
有没有办法可以在表格上执行选择以获取以下内容
FK | Field1 | Field2
=====================
3 | ABC | DEF
谢谢
编辑:为清晰起见修正 field2 名称
【问题讨论】:
【参考方案1】:聚合函数可以帮助您。聚合函数忽略 NULLs
(至少在 SQL Server、Oracle 和 Jet/Access 上是这样),因此您可以使用这样的查询(在 SQL Server Express 2008 R2 上测试):
SELECT
FK,
MAX(Field1) AS Field1,
MAX(Field2) AS Field2
FROM
table1
GROUP BY
FK;
我使用了MAX
,但是任何从GROUP BY
行中选择一个值的聚合都应该可以工作。
测试数据:
CREATE TABLE table1 (FK int, Field1 varchar(10), Field2 varchar(10));
INSERT INTO table1 VALUES (3, 'ABC', NULL);
INSERT INTO table1 VALUES (3, NULL, 'DEF');
INSERT INTO table1 VALUES (4, 'GHI', NULL);
INSERT INTO table1 VALUES (4, 'JKL', 'MNO');
INSERT INTO table1 VALUES (4, NULL, 'PQR');
结果:
FK Field1 Field2
-- ------ ------
3 ABC DEF
4 JKL PQR
【讨论】:
【参考方案2】:根据您未包含的某些数据规则,有几种方法,但这是使用您提供的方法的一种方法。
SELECT
t1.Field1,
t2.Field2
FROM Table1 t1
LEFT JOIN Table1 t2 ON t1.FK = t2.FK AND t2.Field1 IS NULL
另一种方式:
SELECT
t1.Field1,
(SELECT Field2 FROM Table2 t2 WHERE t2.FK = t1.FK AND Field1 IS NULL) AS Field2
FROM Table1 t1
【讨论】:
【参考方案3】:我遇到了类似的问题。不同之处在于我需要对返回的内容进行更多控制,因此我最终得到了一个简单清晰但相当长的查询。这是基于您的示例的简化版本。
select main.id, Field1_Q.Field1, Field2_Q.Field2
from
(
select distinct id
from Table1
)as main
left outer join (
select id, max(Field1)
from Table1
where Field1 is not null
group by id
) as Field1_Q on main.id = Field1_Q.id
left outer join (
select id, max(Field2)
from Table1
where Field2 is not null
group by id
) as Field2_Q on main.id = Field2_Q.id
;
这里的技巧是第一个选择'main'选择要显示的行。然后每个字段都有一个选择。加入的内容应该与“主”查询返回的所有值相同。
请注意,其他查询只需要为每个 id 返回一行,否则您将忽略数据
【讨论】:
【参考方案4】:可能有更简洁的方法,但以下可能是一种方法:
SELECT t.fk,
(
SELECT t1.Field1
FROM `table` t1
WHERE t1.fk = t.fk AND t1.Field1 IS NOT NULL
LIMIT 1
) Field1,
(
SELECT t2.Field2
FROM `table` t2
WHERE t2.fk = t.fk AND t2.Field2 IS NOT NULL
LIMIT 1
) Field2
FROM `table` t
WHERE t.fk = 3
GROUP BY t.fk;
测试用例:
CREATE TABLE `table` (fk int, Field1 varchar(10), Field2 varchar(10));
INSERT INTO `table` VALUES (3, 'ABC', NULL);
INSERT INTO `table` VALUES (3, NULL, 'DEF');
INSERT INTO `table` VALUES (4, 'GHI', NULL);
INSERT INTO `table` VALUES (4, NULL, 'JKL');
INSERT INTO `table` VALUES (5, NULL, 'MNO');
结果:
+------+--------+--------+
| fk | Field1 | Field2 |
+------+--------+--------+
| 3 | ABC | DEF |
+------+--------+--------+
1 row in set (0.01 sec)
在没有WHERE t.fk = 3
子句的情况下运行相同的查询,它将返回以下结果集:
+------+--------+--------+
| fk | Field1 | Field2 |
+------+--------+--------+
| 3 | ABC | DEF |
| 4 | GHI | JKL |
| 5 | NULL | MNO |
+------+--------+--------+
3 rows in set (0.01 sec)
【讨论】:
【参考方案5】:如果一行在 field1 列中具有值,而其他行具有空值,则此查询可能有效。
SELECT
FK,
MAX(Field1) as Field1,
MAX(Field2) as Field2
FROM
(
select FK,ISNULL(Field1,'') as Field1,ISNULL(Field2,'') as Field2 from table1
)
tbl
GROUP BY FK
【讨论】:
【参考方案6】:SELECT Q.FK
,ISNULL(T1.Field1, T2.Field2) AS Field
FROM (SELECT FK FROM Table1
UNION
SELECT FK FROM Table2) AS Q
LEFT JOIN Table1 AS T1 ON T1.FK = Q.FK
LEFT JOIN Table2 AS T2 ON T2.FK = Q.FK
如果有一张表,写Table1而不是Table2
【讨论】:
【参考方案7】:我的情况是我有一张这样的桌子
---------------------------------------------
|company_name|company_ID|CA | WA |
---------------------------------------------
|Costco | 1 |NULL | 2 |
---------------------------------------------
|Costco | 1 |3 |Null |
---------------------------------------------
我希望它如下所示:
---------------------------------------------
|company_name|company_ID|CA | WA |
---------------------------------------------
|Costco | 1 |3 | 2 |
---------------------------------------------
大部分代码几乎相同:
SELECT
FK,
MAX(CA) AS CA,
MAX(WA) AS WA
FROM
table1
GROUP BY company_name,company_ID
唯一的区别是group by
,如果你把两个列名放进去,你可以成对分组。
【讨论】:
以上是关于在 SQL 中合并两行的主要内容,如果未能解决你的问题,请参考以下文章