在SQL Server Management Studio中将单个列连接到单个行

时间:2014-01-03 21:06:05

标签: sql sql-server sql-server-2012

我正在尝试在驱动程序需要接收的给定位置编译转储列表。我有一张这样的桌子:

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

我希望它看起来像这样:

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

我构建的代码如下,但我得到的结果与第一个表相同,只有末尾的空格。

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

非常感谢任何帮助。

2 个答案:

答案 0 :(得分:3)

测试数据

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

<强>查询

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]

结果集

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

答案 1 :(得分:2)

只需使用相关的子查询作为表达式。取结果的独特价值。我在下面的tempdb中创建了一个简单的测试表。

enter image description here

-- 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

所以问题是哪个更快,交叉应用还是子查询?

-- 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

我运行以下内容以打开时间和统计数据。另外,我清除了缓冲区和查询缓存。在阅读之前,这些命令需要10秒钟左右才能完成。

我更改了下面的代码,在tempdb中使用表d1(dumpster)表。比较苹果和苹果。

-- 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 / O是准确的。

--
-- 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.

我想说,两个TSQL语句的表现几乎相同。