在sql server中选择每10行作为一个新列

时间:2017-09-21 13:57:38

标签: sql sql-server group-by

我有一个SQL表,其数据如图所示

Item     Qty
------------
A1       59
A2       76
A3       86
A1       12
A2       17
A3       15
A1       23
A2       39
A3       07

在这里我们可以看到Item重复。所以,我想按Item分组记录。 我想让输出表看起来像下面

 Item    Qty1     Qty2     qty3
----------------------------------
    A1      59       12       23
    A2      76       17       39
    A3      86       15       07

2 个答案:

答案 0 :(得分:2)

pivot与排名函数ROW_NUMBER一起使用:

WITH CTE
AS
(

    SELECT 
      Item, QTy, ROW_NUMBER() OVER(PARTITION BY ITem ORDER BY Item) AS RN
    FROM tablename

)
SELECT Item, [1] AS Qty1, [2] AS Qty2, [3] AS Qty3
FROM CTE
PIVOT
(
    SUM(Qty)
    FOR rn IN([1], [2], [3])
) AS p;

结果:

| Item | Qty1 | Qty2 | Qty3 |
|------|------|------|------|
|   A1 |   59 |   12 |   23 |
|   A2 |   39 |   17 |   76 |
|   A3 |   86 |   15 |    7 |

如果这些数量不是固定的并且它们总是不是3,那么你需要动态地这样做:

DECLARE @cols AS NVARCHAR(MAX);
DECLARE @query AS NVARCHAR(MAX);
DECLARE @colNames AS NVARCHAR(MaX);


select @cols = STUFF((SELECT distinct ',' +
                QUOTENAME(CAST(RN AS NVARCHAR(10)))
                      FROM
                      (
                        SELECT 
      Item, QTy, ROW_NUMBER() OVER(PARTITION BY ITem ORDER BY Item) AS RN
    FROM tablename ) as t
                      FOR XML PATH(''), TYPE
                     ).value('.', 'NVARCHAR(MAX)') 
                        , 1, 1, '');

select @colNames = STUFF((SELECT distinct ',' +
                '[' + CAST(RN AS NVARCHAR(10)) + '] AS Qty' + 
                         CAST(RN AS NVARCHAR(10))
                      FROM
                      (
                        SELECT 
      Item, QTy, ROW_NUMBER() OVER(PARTITION BY ITem ORDER BY Item) AS RN
    FROM tablename ) as t
                      FOR XML PATH(''), TYPE
                     ).value('.', 'NVARCHAR(MAX)') 
                        , 1, 1, '');


SELECT @query = 'WITH CTE
AS
(

    SELECT 
      Item, QTy, ROW_NUMBER() OVER(PARTITION BY ITem ORDER BY Item) AS RN
    FROM tablename

)
SELECT Item,' + @colNames + '
FROM CTE
PIVOT
(
    SUM(Qty)
    FOR rn IN(' + @cols + ')
) AS p;';

execute(@query);

demo

答案 1 :(得分:1)

您可以使用以下角色:

Select * from (
    Select *, Qtys = Concat('Qty', Row_Number() over(partition by Item order by Item))
        from #itemdata
        ) a
    pivot (max(qty) for qtys in ([Qty1],[Qty2],[Qty3])) p

对于动态列表,您可以按以下方式查询:

Declare @cols1 varchar(max)
Declare @query nvarchar(max)

Select @cols1 = stuff((select top (select max(cnt) from (select count(*) cnt from #itemdata group by item ) a) ','+
    QuoteName(Concat('Qty', Row_Number() over(order by (select Null)))) from 
    master..spt_values c1, master..spt_values c2  for xml path('')),1,1,'')

Select @query = ' Select * from (
    Select *, Qtys = Concat(''Qty'', Row_Number() over(partition by Item order by Item))
            from #itemdata
        ) a
    pivot (max(qty) for qtys in (' + @cols1 + ')) p '

Exec sp_executesql @query