Concatenating a single column into a single row in SQL Server Management Studio

北慕城南 提交于 2019-12-23 02:52:57

问题


I am trying to compile a list of dumpsters at a given location that a driver needs to pick up. I have a table like this:

Stop Number   Dumpster Number
------------------------------------    
    1              245
    1              248
    2              312
    2              314
    2              316

I would like it to look like this:

Stop Number    Dumpster Number
-------------------------------
    1          245  248
    2          312  314  316

The code I built is below, but I am getting the same result as the first table, with just the spaces on the end.

SELECT 
    [StopNumber], 
    CAST((CONCAT([ContainerID],'  '))AS VARCHAR) AS ContainersAtStop
FROM 
    [TripSchedule]
GROUP BY 
    StopNumber, (CONCAT([ContainerID],'  '))

Any help would be greatly appreciated.


回答1:


Test Data

DECLARE @t TABLE ([StopNumber] INT, [DumpsterNumber] VARCHAR(10))
INSERT INTO @t
VALUES
(1,'245'),
(1,'248'),
(2,'312'),
(2,'314'),
(2,'316')

Query

SELECT t.[StopNumber] 
       ,STUFF((SELECT ', ' + [DumpsterNumber]
              FROM TestTableOne
              WHERE [StopNumber] = t.StopNumber
              FOR XML PATH(''), TYPE
               ).value('.', 'varchar(max)'), 1, 2, '') AS [DumpsterNumber]
FROM TestTableOne t
GROUP BY t.[StopNumber]

Result Set

╔════════════╦════════════════╗
║ StopNumber ║ DumpsterNumber ║
╠════════════╬════════════════╣
║          1 ║ 245, 248       ║
║          2 ║ 312, 314, 316  ║
╚════════════╩════════════════╝



回答2:


Just use a correlated sub query as an expression. Take the distinct value of the results. I create a simple test table in tempdb below.

-- Just playing
use tempdb
go

-- Remove table 
if object_id('d1') > 0
drop table d1
go

-- Create table
create table d1
(
stop_num int,
dumpster_num varchar(6)
);
go

-- Add data
insert into d1
values
(1, '245'),
(1, '248'),
(2, '312'),
(2, '314'),
(2, '316');
go

-- Sub-query to get list
select 
  stop_num, 
  stuff((
    SELECT ISNULL(dumpster_num,'') + ','
    FROM d1 as inner1
    WHERE inner1.stop_num = outer1.stop_num
    FOR XML PATH('')
  ), 1, 2, '') as list
from d1 as outer1
group by stop_num

So the question is which one is faster, the cross apply or the sub-query?

-- Show time & i/o
SET STATISTICS TIME ON
SET STATISTICS IO ON
GO

-- Remove clean buffers & clear plan cache
CHECKPOINT 
DBCC DROPCLEANBUFFERS 
DBCC FREEPROCCACHE
GO

I ran the following above to turn on time and stats. Also, I cleared out buffers and query cache. Allow a 10 seconds or so for these commands to complete before taking a reading.

I changed the code below to use table d1 (dumpster) table in tempdb. Compare apples to apples.

-- Use a static table in tempdb
SELECT  
    stop_num, 
    STUFF(list.nums, 1 , 2,'') AS dumpster_num
FROM d1 t CROSS APPLY 
    (
        SELECT ', ' + CAST(dumpster_num AS VARCHAR(10))
        FROM d1
        WHERE stop_num = t.stop_num
        FOR XML PATH('')
    ) list(nums)
GROUP BY stop_num

I did get some variance between runs, but taking the best numbers after a buffer/cache clear, the run time is the same. The compile time is a little different. The I/O is exact.

--
-- Cross apply (numbers)
-- 

SQL Server parse and compile time: 
   CPU time = 0 ms, elapsed time = 21 ms.
(2 row(s) affected)

Table 'd1'. 
Scan count 6, logical reads 6, physical reads 0, 
read-ahead reads 0, lob logical reads 0, 
lob physical reads 0, lob read-ahead reads 0.

SQL Server Execution Times:
CPU time = 0 ms,  elapsed time = 14 ms.


--
-- sub query (numbers)
-- 

SQL Server parse and compile time: 
CPU time = 0 ms, elapsed time = 26 ms.

(2 row(s) affected)
Table 'd1'. Scan count 6, logical reads 6, physical reads 0, 
read-ahead reads 0, lob logical reads 0, lob physical reads 0, 
lob read-ahead reads 0.

SQL Server Execution Times:
CPU time = 0 ms,  elapsed time = 14 ms.

I would say, both TSQL statements perform almost the same.



来源:https://stackoverflow.com/questions/20912675/concatenating-a-single-column-into-a-single-row-in-sql-server-management-studio

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!