【问题标题】:Merge two rows in SQL在 SQL 中合并两行
【发布时间】:2011-02-25 20:01:39
【问题描述】:

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

FK | Field1 | Field2
=====================
3  | ABC    | *NULL*
3  | *NULL* | DEF

有没有办法可以在表格上执行选择以获取以下内容

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

谢谢

编辑:为清晰起见修正 field2 名称

【问题讨论】:

    标签: sql join union


    【解决方案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,如果你把两个列名放进去,你可以成对分组。

                【讨论】:

                  猜你喜欢
                  • 2014-10-12
                  • 2020-07-17
                  • 1970-01-01
                  • 2011-08-10
                  • 1970-01-01
                  • 2023-02-19
                  • 2023-01-06
                  • 1970-01-01
                  • 2014-09-27
                  相关资源
                  最近更新 更多