【问题标题】:SQL Server: How to convert column into one row?SQL Server:如何将列转换为一行?
【发布时间】:2011-12-22 16:13:21
【问题描述】:

根据结果,我有一列具有不同的值。 我想返回一行带有固定列。

列输出如下:

Group | Item
--------------
  G1  | 1
  G1  | 2
  G2  | 3

我想输出为:

Group | Item1 | Item2 | Item3
-----------------------------
  G1  |   1   |   2   | N/A
  G2  |   3   |  N/A  | N/A

请帮忙..

在此先感谢...

【问题讨论】:

  • 数据库表的外观如何? (模式)
  • 你有最大的列数吗?
  • 每组可以少或少3个项目..
  • @ankIT 你写了G2 | 3 所以在第 3 项下你应该有 3. 而不是你写的......

标签: sql sql-server sql-server-2005 sql-server-2008 pivot


【解决方案1】:

因为每个组最多可以有三个项目,所以我会使用PIVOT operator

DECLARE @Test TABLE
(
     RowID  INT IDENTITY(1,1) PRIMARY KEY
    ,[Group]VARCHAR(10) NOT NULL
    ,Item   INT NOT NULL
    ,UNIQUE ([Group], Item)
);  
INSERT  @Test   VALUES ('G1', 1);
INSERT  @Test   VALUES ('G1', 2);
INSERT  @Test   VALUES ('G2', 3);

WITH PivotSource
AS
(
    SELECT   t.[Group], t.Item
            ,ROW_NUMBER() OVER(PARTITION BY t.[Group] ORDER BY t.RowID) RowNumber
    FROM    @Test t

)
SELECT   pvt.[Group]
        ,Item1 = ISNULL( CONVERT(VARCHAR(11), pvt.[1]) , 'N/A')
        ,Item2 = ISNULL( CONVERT(VARCHAR(11), pvt.[2]) , 'N/A')
        ,Item3 = ISNULL( CONVERT(VARCHAR(11), pvt.[3]) , 'N/A')
FROM    PivotSource src
PIVOT   ( MAX(src.Item) FOR src.RowNumber IN ([1], [2], [3]) ) pvt;

结果:

Group      Item1       Item2       Item3
---------- ----------- ----------- -----------
G1         1           2           N/A
G2         3           N/A         N/A

【讨论】:

  • 你好 bogdan.. 我认为这将是一项简单的任务,但它并不那么容易.. 实际上我还有一个列 Item_Rate,现在我的表将有 7 列,所以我应该做什么???
  • @RoyiNamir - 现在,它将只返回两行。谢谢。
  • @BogdanSahlean 很好的解决方案。我喜欢 Pivot 和 CTE。
  • @BogdanSahlean 我认为 OP 有一个错误:G2 | 3 这意味着在 item3 下 - 它应该有 3 而不是他/你写的那样。
【解决方案2】:

我想这样的事情会起作用:

SELECT t1.[Group], t1.Item, t2.Item, t3.Item
from tbl t1, tbl t2, tbl t3
where t1.[Group] = t2.[Group] and t1.[Group] = t3.[Group]
    and t1.Item < t2.Item and t2.Item < t3.Item
    and t1.[Group] in (select [Group] from tbl group by [Group] having COUNT(*) = 3)
union
SELECT t1.[Group], t1.Item, t2.Item, NULL
from tbl t1, tbl t2
where t1.[Group] = t2.[Group]
    and t1.Item < t2.Item
    and t1.[Group] in 
    (select [Group] from tbl group by [Group] having COUNT(*) = 2)
union
select tbl.[Group], tbl.Item, NULL, NULL
from tbl
where [Group] in (select [Group] from tbl group by [Group] having COUNT(*) = 1)

【讨论】:

  • 你是对的。我的解决方案在性能方面不是很优雅(它使用了很多笛卡尔积和子查询)。
【解决方案3】:

由于您有固定数量的输出列,您可以使用ROW_NUMBER()over (partition by ... order by ...) 做一些技巧。

select child1.[Group], child1.Item as Item1, child2.Item as Item2, child3.Item as Item3 from 
(select [Group], Item from 
    (select  [Group], Item, (ROW_NUMBER() over(partition by [group] order by item)) as rownum from GroupTable) as child1_inner
    where child1_inner.rownum = 1) as child1
left outer join 
(select [Group], Item from 
    (select  [Group], Item, (ROW_NUMBER() over(partition by [group] order by item)) as rownum from GroupTable) as child2_inner
    where child2_inner.rownum = 2) as child2
on child1.[Group] = child2.[Group]
left outer join 
(select [Group], Item from 
    (select  [Group], Item, (ROW_NUMBER() over(partition by [group] order by item)) as rownum from GroupTable) as child3_inner
    where child3_inner.rownum = 3) as child3
on child1.[Group] = child3.[Group]

这将返回 null 而不是 N/A,但您可以使用 COALESCE 修复它。

【讨论】:

    猜你喜欢
    • 2019-07-16
    • 2015-12-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-02-24
    • 2010-10-22
    • 2013-02-12
    相关资源
    最近更新 更多