我有两张表格如下:
TABLE:CITY
CITY_ID CITY
----------------
1 London
2 Chicago
3 Newyork
4 Delhi
TABLE:TRAIN
TRAIN_ID CITY_TRAVELS
----------------------
1111 1,3
2222 4
3333 1,2
4444 2,3
我想写一个查询,它应该给出以下结果: TRAIN表中的CITY_TRAVELS也是VARCHAR类型 CITY表的CITY_ID和INT的类型。 查询结构将如何?
TRAIN_ID CITY
-------------------------
1111 London,Newyork
2222 Delhi
3333 London,Chicago
4444 Chicago,Newyork
由于 萨蒂亚吉特
答案 0 :(得分:5)
结构很糟糕,但你可以在一些UDF中解析逗号分隔的字符串,并使用子查询将数字连接到城市。希望文章"Split Function in Sql Server to break Comma-Separated Strings into Table"能帮到你!
答案 1 :(得分:4)
-- sample data
declare @City table
(
CityID int,
City varchar(50)
)
declare @Train table
(
TrainID int,
CityTravels varchar(50)
)
insert into @City
select 1, 'London'
union all
select 2, 'Chicago'
union all
select 3, 'Newyork'
union all
select 4, 'Delhi'
insert into @Train
select 1111, '1,3'
union all
select 2222, '4'
union all
select 3333, '1,2'
union all
select 4444, '2,3'
-- solution
;with cte as
(
select
t1.TrainID, t2.City
from
(
select
TrainID,
-- t2.c - the xml tag that function nodes provides
-- query('data(.)') gets the value of the tag
CityID = cast(cast(t2.c.query('data(.)') as varchar) as int)
from
(
select
TrainID,
-- represent Cities list in the xml,
-- which is proper for xquery node function
-- for example <root><a>1</a><a>2</a></root>
CityTravelsXml = cast('<root><a>' + replace(CityTravels, ',', '</a><a>') + '</a></root>' as xml)
from @Train
) t1
-- xquery nodes function for each tag /root/a returns a separate row
-- with single column the represents the tag
cross apply CityTravelsXml.nodes('/root/a') t2(c)
) t1
join @City t2 on t1.CityID = t2.CityID
)
select
TrainID,
-- truncate the last comma
Cities = case when Cities is not null then substring(Cities, 1, len(Cities) - 1) end
from
(
select
TrainID,
Cities =
(
-- for xml here concatenates strings in a column
select
City + ','
from cte t2
where t2.TrainID = t1.TrainID
for xml path('')
)
from @Train t1
) t
修改:删除了第二个解决方案,因为经过一些测试后,它显示出不合适的效果,尽管它对表格的引用较少。
答案 2 :(得分:1)
create database train
create table city(
city_id int identity(1,1),
city varchar(max)
)
create table train(
train_id int identity(1111,1111),
city_travels varchar(max)
)
insert into city values ('London');
insert into city values ('Chicago');
insert into city values ('NewYork');
insert into city values ('Delhi');
insert into train values ('1,3,4');
insert into train values ('4');
insert into train values ('1,2');
insert into train values ('1,2,3,4');
create table #train(
train_id int,
city varchar(max)
)
declare @count int, @id int,@first int;
declare @train_id int,@index int;
declare @city_travels varchar(max),@city_name varchar(max);
set @city_name=null;
declare train_cursor CURSOR for
select train_id,city_travels from train
open train_cursor
fetch next from train_cursor into @train_id,@city_travels
while (@@fetch_status=0)
begin
set @first=0;
set @index = charindex(',',@city_travels);
if(@index!=0)
begin
if(@first=0)
begin
set @id=convert (int,substring(@city_travels,1,@index-1));
set @city_travels=substring(@city_travels,@index+1,len(@city_travels));
set @city_name=((select city from city where city_id=@id)+',');
set @index=charindex(',',@city_travels);
set @first=1;
end
while(@index!=0)
begin
set @id=convert (int,substring(@city_travels,1,@index-1));
set @city_travels=substring(@city_travels,@index+1,len(@city_travels));
set @index=charindex(',',@city_travels)
set @city_name=(@city_name+(select city from city where city_id=@id)+',');
end
set @id=convert (int,@city_travels);
set @city_name=(@city_name+(select city from city where city_id=@id));
insert into #train values (@train_id,@city_name);
set @city_name=null;
end
else
begin
set @id=convert (int,@city_travels);
set @city_name=(select city from city where city_id=@id);
insert into #train values (@train_id,@city_name);
set @city_name=null;
end
fetch next from train_cursor into @train_id,@city_travels
end
select * from city;
select * from train;
select * from #train;
close train_cursor
deallocate train_cursor
truncate table #train