【问题标题】:How to write a pivot for this如何为此编写支点
【发布时间】:2019-11-22 02:54:58
【问题描述】:

我有下表:

+---------+-------+
| unit_id | Code  |
+---------+-------+
|  214825 | D1821 |
|  214825 | D0235 |
|  214825 | D0710 |
+---------+-------+

我想要一个执行以下操作的查询:

+---------+-------+-------+-------+
| unit_id | code1 | code2 | code3 |
+---------+-------+-------+-------+
|  214825 | D1821 | D0235 | D0710 |
+---------+-------+-------+-------+

我尝试了 pivot 但它需要我对数据求和,还有其他方法吗?

【问题讨论】:

  • 是否有任何其他列值指示代码中的值应放置到 code1 或 code2 或 code3 中?
  • 没有,但我知道每个 unit_id 都有 3 个值。

标签: sql sql-server tsql pivot


【解决方案1】:

您可以使用下面的 row_number 来满足您的要求。这样,三个不同列中的代码值将随机放置(如果在生成 row_number 时没有排序选择)或您应用的升序/降序(如在我的查询中)-

您可以查看DEMO HERE

SELECT unit_id, 
MAX(CASE WHEN  RN = 1 THEN Code ELSE NULL END) code1,
MAX(CASE WHEN  RN = 2 THEN Code ELSE NULL END) code2,
MAX(CASE WHEN  RN = 3 THEN Code ELSE NULL END) code3
FROM
(
    SELECT *,
    ROW_NUMBER() OVER (PARTITION BY unit_id ORDER BY Code) RN
    -- Here row number will generate for default ascending order over value from column "Code"
    FROM your_table
)A
GROUP BY unit_id

【讨论】:

    【解决方案2】:

    如果您使用的是 SQL Server 2016(或更高版本),这里是基于 xml 和 string_agg 的替代解决方案:

    declare @tmp table (unit_id int ,Code varchar(50))
    
    insert into @tmp
    values 
      (214825,'d1821')
     ,(214825,'d0235')
     ,(214825,'d0710')
    
    ;with splitted
    as (
        select unit_id
            ,cast('<x>' + REPLACE(string_agg(Code,'_'), '_', '</x><x>') + '</x>' as xml) as Parts
        from @tmp
        group by unit_id
        )
    select unit_id
        ,Parts.value(N'/x[1]', 'varchar(50)') AS code1      
        ,Parts.value(N'/x[2]', 'varchar(50)') AS code2
        ,Parts.value(N'/x[3]', 'varchar(50)') AS code3
    from Splitted
    

    结果:

    【讨论】:

      猜你喜欢
      • 2021-06-02
      • 2018-08-14
      • 1970-01-01
      • 2011-02-21
      • 1970-01-01
      • 2012-02-29
      • 2011-09-03
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多