如何通过分组合并成多个列?

时间:2017-07-27 06:29:32

标签: sql-server tsql sql-server-2016

如果您运行以下代码,您将得到如下所示的结果:

ITEM    DIFF_QTY        DATE_OUTGO                              WAREH  COMPANY
1000    -5, -3, -4,     2017-08-01, 2017-08-02, 2017-08-03,     WH     CMP

哪个好,这是我要找的输出。遗憾的是,这仅在选择了特定的 ITEM 时才有效。如果我删除 WHERE ,则所有内容都放在同一行输出中。

那么我如何通过分组(ITEM,WAREH,COMPANY)来分隔结果?因此,最终结果将如下所示:

ITEM    DIFF_QTY        DATE_OUTGO                              WAREH  COMPANY
1000    -5, -3, -4,     2017-08-01, 2017-08-02, 2017-08-03,     WH     CMP
1001    -10, -13        2017-08-01, 2017-08-03                  WH     CMP

代码

DECLARE @tempTable TABLE (
    ITEM nvarchar(32),
    DIFF_QTY nvarchar(6), 
    DATE_OUTGO nvarchar(10),
    WAREH nvarchar(5),
    COMPANY nvarchar(5)
)

INSERT INTO @tempTable (ITEM, DIFF_QTY, DATE_OUTGO, WAREH, COMPANY)
VALUES 
(1000, '-5', '2017-08-01', 'WH', 'CMP'),
(1000, '-3', '2017-08-02', 'WH', 'CMP'),
(1000, '-4', '2017-08-03', 'WH', 'CMP'),
(1001, '-10', '2017-08-01', 'WH', 'CMP'),
(1001, '-13', '2017-08-03', 'WH', 'CMP')

SELECT * 
FROM @tempTable

DECLARE @itemNum nvarchar(32)
DECLARE @diffQty nvarchar(max)
DECLARE @dateOutgo nvarchar(max)
DECLARE @warehouse nvarchar(5)
DECLARE @company nvarchar(5)

SET @diffQty = ''
SET @dateOutgo = ''

SELECT 
    @itemNum = ITEM, 
    @diffQty = @diffQTY + DIFF_QTY + ', ',
    @dateOutgo = @dateOutgo + DATE_OUTGO + ', ', 
    @warehouse = WAREH, 
    @company = COMPANY 
FROM 
    @tempTable
WHERE 
    ITEM = 1000

SELECT @itemNum ITEM_NUM, @diffQty DIFF_QTY, @dateOutgo DATE_OUTGO, @warehouse WAREHOUSE, @company COMPANY

我看过多个关于合并的线程,但几乎每个解决方案都要求你不要同时做多件事(SELECT,GROUP,COALESCE,Multiple columns等......)

3 个答案:

答案 0 :(得分:2)

您不能使用标量变量(如@itemNum nvarchar(32))来存储表格数据。

您希望实现的输出最常在SQL Server中使用FOR XML PATH

生成
SELECT t.ITEM,
       STUFF((SELECT  ',' + x.DIFF_QTY
              FROM @tempTable AS x
              WHERE x.ITEM = t.ITEM AND 
                    x.WAREH = t.WAREH AND
                    x.COMPANY = t.COMPANY
              FOR XML PATH('')), 1, 1, '') AS DIFF_QTY,
       STUFF((SELECT  ',' + x.DATE_OUTGO
              FROM @tempTable AS x
              WHERE x.ITEM = t.ITEM AND 
                    x.WAREH = t.WAREH AND
                    x.COMPANY = t.COMPANY
              FOR XML PATH('')), 1, 1, '') AS DATE_OUTGO
FROM @tempTable AS t
GROUP BY t.ITEM, t.WAREH, t.COMPANY

输出:

ITEM    DIFF_QTY    DATE_OUTGO
-----------------------------------------------------
1000    -5,-3,-4    2017-08-01,2017-08-02,2017-08-03
1001    -10,-13     2017-08-01,2017-08-03

答案 1 :(得分:1)

您可以使用FOR XML PATH('')来连接值:

SELECT
    t1.ITEM,
    a.DIFF_QTY,
    b.DATE_OUTGO,
    t1.WAREH,
    t1.COMPANY
FROM @tempTable t1
CROSS APPLY(
    SELECT DIFF_QTY =  STUFF((
        SELECT ', ' + CAST(t2.DIFF_QTY AS VARCHAR(100))
        FROM @tempTable t2
        WHERE
            t2.ITEM = t1.ITEM
            AND t2.WAREH = t1.WAREH
            AND t2.COMPANY = t2.COMPANY
        ORDER BY t2.DATE_OUTGO
        FOR XML PATH('')
    ), 1, 1, '')  
) a
CROSS APPLY(
    SELECT DATE_OUTGO = STUFF((
        SELECT ', ' + CAST(t2.DATE_OUTGO AS VARCHAR(10))
        FROM @tempTable t2
        WHERE
            t2.ITEM = t1.ITEM
            AND t2.WAREH = t1.WAREH
            AND t2.COMPANY = t2.COMPANY
        ORDER BY t2.DATE_OUTGO
        FOR XML PATH('')
    ), 1, 1, '')  
) b
GROUP BY
    t1.ITEM, t1.WAREH, t1.COMPANY, a.DIFF_QTY, b.DATE_OUTGO

答案 2 :(得分:1)

DECLARE @tempTable TABLE (
    ITEM nvarchar(32),
    DIFF_QTY nvarchar(6), 
    DATE_OUTGO nvarchar(10),
    WAREH nvarchar(5),
    COMPANY nvarchar(5)
)

INSERT INTO @tempTable (ITEM, DIFF_QTY, DATE_OUTGO, WAREH, COMPANY)
VALUES 
(1000, '-5', '2017-08-01', 'WH', 'CMP'),
(1000, '-3', '2017-08-02', 'WH', 'CMP'),
(1000, '-4', '2017-08-03', 'WH', 'CMP'),
(1001, '-10', '2017-08-01', 'WH', 'CMP'),
(1001, '-13', '2017-08-03', 'WH', 'CMP')

SELECT * 
FROM @tempTable

DECLARE @itemNum nvarchar(32)
DECLARE @diffQty nvarchar(max)
DECLARE @dateOutgo nvarchar(max)
DECLARE @warehouse nvarchar(5)
DECLARE @company nvarchar(5)

SET @diffQty = ''
SET @dateOutgo = ''



SELECT distinct  ITEM , 

              STUFF((SELECT ', ' + CAST(DIFF_QTY AS NVARCHAR(MAX)) [text()]
         FROM  @tempTable temp
         where t.ITEM=temp.ITEM                                         
         FOR XML PATH(''), TYPE)
        .value('.','NVARCHAR(MAX)'),1,2,'')  DIFF_QTY, 

                      STUFF((SELECT ', ' + CAST(DATE_OUTGO AS NVARCHAR(MAX)) [text()]
         FROM  @tempTable temp      
          where t.ITEM=temp.ITEM                                   
         FOR XML PATH(''), TYPE)
        .value('.','NVARCHAR(MAX)'),1,2,'')  DATE_OUTGO,
        WAREH,COMPANY
        from @tempTable t

希望它完全符合您的要求