0

我正在使用 SQL Server 2008。

这是我的桌子。

表 A

 Aid int pk
 col2
 col3
 XYZID int

表 B

 Bid int pk
 XYZID int
 Col2
 Col3 
 Col4
 seq -- (Sequence )

Table B会是这样

seq   col2    |XYZID|Bid |col3| col4 
===============================================
  1   foo     | 1   |  1 | 12 | wqw
  3   bar     | 1   | 10 | 77 | kikk
  2   foobar  | 1   |  2 |  w | ed
  1   barfoo  | 2   |  4 |  e | dwe
  2   asdsad  | 2   |  5 |  e | e 

Table A是主表,基于XYZIDA

我需要使用 col from TableBwith生成一个字符串值XYZID and Seq

我需要使用带有 XYZID 和 Seq 的 TableB 中的 col 生成一个字符串值。

例如:xyzid= 1

我期望 :foo-12-wqw#foobar-w-ed#bar-77-kikk

基于Sequence foo-1,foobar-2,bar-3

4

2 回答 2

4

对于XYZID = 1.

select stuff((select '#'+col2+'-'+col3+'-'+col4
              from TableB
              where XYZID = 1
              order by seq
              for xml path(''), type).value('.', 'nvarchar(max)'), 1, 1, '')

对于 TableA 中的所有行:

select stuff((select '#'+col2+'-'+col3+'-'+col4
              from TableB as B
              where A.XYZID = B.XYZID
              order by seq
              for xml path(''), type).value('.', 'nvarchar(max)'), 1, 1, '')
from TableA as A
于 2012-06-21T12:34:12.623 回答
2

DDL:

drop table tblx;
create table tblx
(
seq int,
col2 varchar(50),
xyzid int,
bid int,
col3 varchar(50),
col4 varchar(50)
);

数据:

insert into tblx(seq,col2,xyzid,bid,col3,col4) values
(1,   'foo'     , 1,   1,  '12', 'wqw'),
(3,   'bar'     , 1,   10, '77', 'kikk'),
(2,   'foobar'  , 1,   2,  'w',  'ed'),
(1,   'barfoo'  , 2,   4,  'e',  'dwe'),
(2,   'asdsad'  , 2,   5,  'e',  'e');

使用 CTE 方法:

with a(xyzid, seq, x) as
(
select xyzid, seq, cast(col2 + '-' + col3 + '-' + col4 as varchar(max)) as x
from tblx
where seq = 1
union all
select t.xyzid, t.seq, a.x + '#' + (t.col2 + '-' + t.col3 + '-' + t.col4)
from tblx t
join a on a.xyzid = t.xyzid and t.seq = a.seq + 1
)
select xyzid, rtrim(x) as x 
from a w
where seq = (select MAX(seq) from a where xyzid = w.xyzid)
order by xyzid;

输出:

xyzid       x
----------- -----------------------------------
1           foo-12-wqw#foobar-w-ed#bar-77-kikk
2           barfoo-e-dwe#asdsad-e-e

(2 row(s) affected)

使用主表(例如表 A)只需要对查询进行简单的修改:

with a(xyzid, seq, x) as
(
select xyzid, seq, cast(col2 + '-' + col3 + '-' + col4 as varchar(max)) as x
from tblx
where seq = 1
union all
select t.xyzid, t.seq, a.x + '#' + (col2 + '-' + col3 + '-' + col4)
from tblx t
join a on a.xyzid = t.xyzid and t.seq = a.seq + 1
)
select w.xyzid, rtrim(x) as x 
from tblA w -- just add this main table
left join a on a.xyzid = w.xyzid 
               and seq = (select MAX(seq) from a where xyzid = w.xyzid)
order by xyzid;

数据:

create table tblA
(
aid int identity(1,1) primary key,
col2 varchar(50),
col3 varchar(50),
xyzid int
);


insert into tblA(col2,col3,xyzid) values
('','',1),
('','',2),
('','',3);

输出:

xyzid       x
----------- ------------------------------------
1           foo-12-wqw#foobar-w-ed#bar-77-kikk
2           barfoo-e-dwe#asdsad-e-e
3           NULL

(3 row(s) affected)

如果 seq 字段不连续和/或不唯一,请放置一个序列器:

with sequencer as
(
select 
    xyzid, ROW_NUMBER() over(partition by xyzid order by seq) as seq
    , col2, col3, col4 
from tblx 
)
,a(xyzid, seq, x) as
(
select xyzid, seq, cast(col2 + '-' + col3 + '-' + col4 as varchar(max)) as x
from sequencer
where seq = 1
union all
select t.xyzid, t.seq, a.x + '#' + (col2 + '-' + col3 + '-' + col4)
from sequencer t
join a on a.xyzid = t.xyzid and t.seq = a.seq + 1
)
select w.xyzid, rtrim(x) as x 
from tblA w
left join a on a.xyzid = w.xyzid 
            and seq = (select MAX(seq) from a where xyzid = w.xyzid)
order by xyzid;

示例非连续序列:

insert into tblx(seq,col2,xyzid,bid,col3,col4) values
(1,   'foo'     , 1,   1,  '12', 'wqw'),
(5,   'bar'     , 1,   10, '77', 'kikk'),
(3,   'foobar'  , 1,   2,  'w',  'ed'),
(1,   'barfoo'  , 2,   4,  'e',  'dwe'),
(3,   'asdsad'  , 2,   5,  'e',  'e');

输出(仍然相同):

xyzid       x
----------- --------------------------------------
1           foo-12-wqw#foobar-w-ed#bar-77-kikk
2           barfoo-e-dwe#asdsad-e-e
3           NULL

(3 row(s) affected)

关于速度,它仍然很快。与 XML 方法相比,CTE 查询成本为 5%,即 95%

于 2012-06-21T12:58:33.593 回答