【问题标题】:Selecting multiple values into single row - SQL server在单行中选择多个值 - SQL Server
【发布时间】:2019-02-20 13:15:10
【问题描述】:

我需要像这样合并一个带有 ID 和各种位标志的表

-----------------
a1 | x |   | x |
-----------------
a1 |   | x |   |
-----------------
a1 |   |   |   |
-----------------
b2 | x |   |   |
-----------------
b2 |   |   |   |
-----------------
c3 | x | x | x |

变成这样的形式

-----------------
a1 | x | x | x |
-----------------
b2 | x |   |   |
-----------------
c3 | x | x | x |

问题是数据是按选项 ID 连接的,每个选项都有一个唯一的 ID,它与 a1、b2 连接。当我尝试使用 DISTINCT 选择它时,我从表号 1 收到结果。我可以通过 SELECT 中的子查询来实现它,但由于性能原因,它确实是弱解决方案。

您知道如何选择所有这些标志并将其组合成一行吗?

【问题讨论】:

  • 简单分组。

标签: sql sql-server


【解决方案1】:

使用聚合

select col1 ,max(col2),max(col3),max(col4)
form table_name group by col1

【讨论】:

    【解决方案2】:

    对于给定的结果集,可以使用MINGROUP BY

    SELECT 
    tbl.Col
    , MIN(tbl.Col1) Col1
    , MIN(tbl.Col2) Col2 
    , MIN(tbl.Col3) Col3 
    FROM @table tbl
    GROUP BY tbl.Col
    

    但是,如果您有空行,请使用MAX()。否则 MIN() 返回空行:

    SELECT 
    tbl.Col
    , MAX(tbl.Col1) Col1
    , MAX(tbl.Col2) Col2 
    , MAX(tbl.Col3) Col3 
    FROM @table tbl
    GROUP BY tbl.Col
    

    例如:

    DECLARE @table TABLE
    (
        Col  VARCHAR(50),
        Col1 VARCHAR(50), 
        Col2 VARCHAR(50), 
        Col3 VARCHAR(50) 
    )
    
    INSERT INTO @table
    (
        Col,
        Col1,
        Col2,
        Col3
    )
    VALUES
    (   'a1', -- Col - varchar(50)
        'x', -- Col1 - varchar(50)
        Null, -- Col2 - varchar(50)
        'x'  -- Col3 - varchar(50)
        )
    , ('a1', NULL, 'x', null)
    , ('a1', NULL, 'x', null)
    , ('b2', 'x', null, null)
    , ('b2', null, null, null)
    , ('c3', 'x', 'x', 'x')
    
    SELECT 
    tbl.Col
    , MIN(tbl.Col1) Col1
    , MIN(tbl.Col2) Col2 
    , MIN(tbl.Col3) Col3 
    FROM @table tbl
    GROUP BY tbl.Col
    

    输出:

    Col Col1    Col2    Col3
    a1   x        x       x
    b2   x       NULL   NULL
    c3   x        x       x
    

    【讨论】:

    • @Larnu 是的,对于这个结果集,它可以正常工作。
    • 我不明白。 MIN 会跳过空值,MAX 不会?这对我来说是新的。
    • MINMAX 都忽略空值所以都返回非空值。只有当每个 ID 存在两个或多个非空值时,MIN 才会返回较小的值,MAX 会返回较大的值。这与“空行”无关。
    【解决方案3】:

    你想要聚合:

    select col1, max(col2), max(col2), max(col3)
    from table t
    group by col1;
    

    这假设空白值为null

    【讨论】:

      【解决方案4】:

      这种情况的一般解决方案是简单地聚合并在列上使用MINMAX

      然而,SQL Server 的数据类型BIT 很古怪。它有点像BOOLEAN,但不是真正的布尔值。它有点像一个非常有限的数字数据类型,但它也不是真正的数字类型。而且这种数据类型根本不存在聚合函数。在标准 SQL 中,BOOLEAN 类型有 ANYEVERY。在 PostgreSQL 中,BIT_ORBIT_AND 对应 BITBOOL_ORBOOL_AND 对应 BOOLEAN。 SQL Server 什么都没有。

      因此,在使用MIN(按位与)或MAX(按位或)之前将列转换为数字类型。例如

      select
        id,
        max(bit1 + 0) as bit1agg,
        max(bit2 + 0) as bit2agg,
        max(bit3 + 0) as bit3agg
      from mytable
      group by id
      order by id;
      

      您当然也可以使用CASTCONVERT

      【讨论】:

      • 是的,我将 Bit 转换为整数,它工作正常 :) 谢谢您的回复
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-04-30
      • 2021-10-29
      • 1970-01-01
      • 2021-03-28
      • 2021-10-05
      • 2013-09-16
      • 1970-01-01
      相关资源
      最近更新 更多