在SQL中合并两行

在SQL中合并两行,sql,join,union,Sql,Join,Union,假设我有一个包含以下信息的表: FK | Field1 | Field2 ===================== 3 | ABC | *NULL* 3 | *NULL* | DEF 是否有一种方法可以在表上执行select以获得以下内容 FK | Field1 | Field2 ===================== 3 | ABC | DEF 谢谢 编辑:为清晰起见,请修复字段2名称根据您未包含的某些数据规则,有几种方法,但这里有一种方法可以使用您提供的数据规则

假设我有一个包含以下信息的表:

FK | Field1 | Field2
=====================
3  | ABC    | *NULL*
3  | *NULL* | DEF
是否有一种方法可以在表上执行select以获得以下内容

FK | Field1 | Field2
=====================
3  | ABC    | DEF
谢谢


编辑:为清晰起见,请修复字段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

可能有更简洁的方法,但以下方法可能是一种方法:

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)

聚合函数在这方面可能会有所帮助。聚合函数忽略
null
(至少在SQL Server、Oracle和Jet/Access上是这样),因此可以使用这样的查询(在SQL Server Express 2008 R2上测试):

我使用了
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

我也有类似的问题。不同之处在于,我需要对返回的内容进行更多的控制,因此我最终得到了一个简单、清晰但相当长的查询。下面是基于您的示例的简化版本

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”选择要显示的行。然后,每个字段有一个select。连接的对象应该是“main”查询返回的所有相同值


请注意,这些其他查询每个id只需要返回一行,否则您将忽略数据。如果一行在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

我的情况是我有一张这样的桌子

---------------------------------------------
|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
唯一的区别是
分组依据
,如果在其中放入两个列名,则可以成对分组

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
如果有一个表,写下表1而不是表2

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