SQL Server中的多个复杂字符串连接

时间:2017-09-25 17:57:58

标签: sql-server

我需要一些帮助。我已经使用STUFFFOR XML创建了以下几乎我想要的结果。我只需要更进一步,以便每个pid都有1条路线。

所以我有这个SQL代码:

select 
    pid, 
    STUFF((select ' ' + 
               right('00' + cast(direction as nvarchar(MAX)), 2) + ':' +
               + CAST(node_id AS NVARCHAR(MAX))
           from Path_Devices
           where (path_id = paths.path_id)
           group by path_id, node_id, node_index
           order by path_id, node_index
           FOR XML PATH(''), TYPE).value('(./text())[1]', 'VARCHAR(MAX)'), 1, 2, '') AS ROUTE
from 
    Path_Devices paths
join 
    Path p on p.id = paths.path_id
group by 
    path_id, pid, direction

产生这个:

enter image description here

我需要在ROUTE列上再执行一次连接,以便我的结果集是每个pid 1个完整路由,如下所示:

enter image description here

我的偏好是让整个结果由数据库生成,而不需要在后端进行任何Java处理。此外,这将是使用JdbcTemplate创建和传递的更大select语句的一部分。目标是在不对数据库进行任何更改或添加存储过程的情况下实现此目的。只是让它变得更具挑战性。 ; - )

所以问题是我如何堆叠行字符串值的多个连接以获得我想要的结果?提前感谢您提供任何帮助!

以下是我的表格:

CREATE TABLE [dbo].[Path](
    [id] [int] IDENTITY(1,1) NOT NULL,
    [direction] [tinyint] NOT NULL,
    [pid] [uniqueidentifier] NULL
) ON [PRIMARY]

set identity_insert Path ON
insert into Path (id, direction, pid) values 
    (1,0,'7E814659-1BE3-4941-9710-D78731E70E07'),
    (2,1,'7E814659-1BE3-4941-9710-D78731E70E07') ,
    (3,0,'67C8CB0D-8AFD-46E4-B06C-70EA19A949A3'),
    (4,1,'67C8CB0D-8AFD-46E4-B06C-70EA19A949A3'),
    (5,0,'9DADA1DD-F73C-4210-8DDD-A000ED1B9325'),
    (6,1,'9DADA1DD-F73C-4210-8DDD-A000ED1B9325'),
    (7,0,'BC2CF5D6-08EB-4530-B354-818039F24A8F'),
    (8,1,'BC2CF5D6-08EB-4530-B354-818039F24A8F'),
    (9,0,'BC2CF5D6-08EB-4530-B354-818039F24A8F'),
    (10,1,'BC2CF5D6-08EB-4530-B354-818039F24A8F')

CREATE TABLE [dbo].[Path_Devices](
    [path_id] [int] NOT NULL,
    [node_id] [int] NOT NULL,
    [node_index] [int] NOT NULL
) ON [PRIMARY]

insert into Path_Devices (path_id, node_id, node_index) values 
    (1,21,0),
    (1,2024,1),
    (1,2023,2),
    (1,2022,3),
    (1,2011,4),
    (2,2011,0),
    (2,2042,1),
    (2,2043,2),
    (2,2044,3),
    (2,41,4),
    (3,21,0),
    (3,2024,1),
    (3,2023,2),
    (3,2022,3),
    (3,2011,4),
    (4,2011,0),
    (4,2042,1),
    (4,2043,2),
    (4,2044,3),
    (4,41,4),
    (5,60,0),
    (5,2062,1),
    (5,2081,2),
    (6,2081,0),
    (6,2072,1),
    (6,2073,2),
    (6,70,3),
    (7,41,0),
    (7,2044,1),
    (8,2044,0),
    (8,3802,1),
    (9,3802,0),
    (9,2073,1),
    (9,2072,2),
    (9,2071,3 )

使用SQL Server 2012或2014。

2 个答案:

答案 0 :(得分:0)

您使用的是哪个版本,以下是基于2012 +。

;with Path_Devices(pid,path_id,direction,node_id) AS (
    select 'aaaaaaaaaaaaaaaa',1,0,21 union all
    select 'aaaaaaaaaaaaaaaa',1,0,2024 union all
    select 'aaaaaaaaaaaaaaaa',1,0,2023 union all
    select 'aaaaaaaaaaaaaaaa',1,0,2022 union all
    select 'aaaaaaaaaaaaaaaa',1,0,2021 union all
    select 'aaaaaaaaaaaaaaaa',2,1,2011 union all
    select 'aaaaaaaaaaaaaaaa',2,1,2042 union all
    select 'aaaaaaaaaaaaaaaa',2,1,2043 union all
    select 'aaaaaaaaaaaaaaaa',2,1,2044 union all
    select 'aaaaaaaaaaaaaaaa',2,1,41 
  )
  /* your statement
  select 
    pid, 
    STUFF((select ' ' + 
               right('00' + cast(direction as nvarchar(MAX)), 2) + ':' +
               + CAST(node_id AS NVARCHAR(MAX))
           from Path_Devices
           where (path_id = paths.path_id)
           group by path_id,direction, node_id
           order by path_id
           FOR XML PATH(''), TYPE).value('(./text())[1]', 'VARCHAR(MAX)'), 1, 2, '') AS ROUTE
from Path_Devices paths
group by path_id, pid, direction
*/
  select 
    pid, 
    STUFF((select case when LAG(direction)over(partition by pid order by path_id,direction)=direction then ' ' else ',' end + 
               right('00' + cast(direction as nvarchar(MAX)), 2) + ':' +
               + CAST(node_id AS NVARCHAR(MAX))
           from Path_Devices
           where (pid = paths.pid)
           group by pid,path_id,direction, node_id
           order by path_id,direction
           FOR XML PATH(''), TYPE).value('(./text())[1]', 'VARCHAR(MAX)'), 1, 2, '') AS ROUTE
from Path_Devices paths
group by pid
+------------------+----------------------------------------------------------------------------+
| pid              | ROUTE                                                                      |
+------------------+----------------------------------------------------------------------------+
| aaaaaaaaaaaaaaaa | 0:21 00:2024 00:2023 00:2022 00:2021,01:2011 01:2042 01:2043 01:2044 01:41 |
+------------------+----------------------------------------------------------------------------+

答案 1 :(得分:0)

您可以尝试这样的事情:

with cte as (
select 
    pid, 
    STUFF((select ' ' + 
               right('00' + cast(direction as nvarchar(MAX)), 2) + ':' +
               + CAST(node_id AS NVARCHAR(MAX))
           from Path_Devices
           where (path_id = paths.path_id)
           group by path_id, node_id, node_index
           order by path_id, node_index
           FOR XML PATH(''), TYPE).value('(./text())[1]', 'VARCHAR(MAX)'), 1, 2, '') AS ROUTE
from 
    Path_Devices paths
join 
    Path p on p.id = paths.path_id
group by 
    path_id, pid, direction
)
select Distinct
    pid, 
    STUFF((select ' ' + 
               b.route
           from cte b
           where (a.pid = b.pid)
           group by b.pid, b.route
           order by b.pid, b.route
           FOR XML PATH(''), TYPE).value('(./text())[1]', 'VARCHAR(MAX)'), 1, 2, '') AS ROUTE
from 
    cte A