SQL Server问题:
我有一个表,其中包含一个包含外键列表的列
| ID | PRICE | LIST_OF_FOREIGN_IDS |
------------------------------------
| 3 | 89 | 67,68,69 |
| 4 | 120 | 45,46 |
我需要一个带有单个ID和每行FOREIGN_ID
的视图。
| ID | PRICE | FOREIGN_ID |
---------------------------
| 3 | 89 | 67 |
| 3 | 89 | 68 |
| 3 | 89 | 69 |
| 4 | 120 | 45 |
| 4 | 120 | 46 |
是否有人知道获取第二张表中的数据的解决方案?
答案 0 :(得分:5)
如果可能,您需要在此表上修复数据库设计,这样您就不会存储逗号单独的值列表。这将很难维持。
理想情况下,您的表结构可能会改变如下:
create table item_details
(
id int,
price int
);
create table foreign_details
(
id int,
details varchar(50)
);
create table item_foreign
(
item_id int,
foreign_id int
);
然后您将使用查询获得结果:
select i.id, i.price, f.id
from item_details i
inner join item_foreign ifd
on i.id = ifd.item_id
inner join foreign_details fd
on ifd.foreign_id = f.id
如果无法修复当前的表结构,则可以使用拆分功能将数据分成多行。示例函数可以是:
CREATE FUNCTION [dbo].[Split](@String varchar(MAX), @Delimiter char(1))
returns @temptable TABLE (items varchar(MAX))
as
begin
declare @idx int
declare @slice varchar(8000)
select @idx = 1
if len(@String)<1 or @String is null return
while @idx!= 0
begin
set @idx = charindex(@Delimiter,@String)
if @idx!=0
set @slice = left(@String,@idx - 1)
else
set @slice = @String
if(len(@slice)>0)
insert into @temptable(Items) values(@slice)
set @String = right(@String,len(@String) - @idx)
if len(@String) = 0 break
end
return
end;
然后你将使用CROSS APPLY传入逗号分隔列表中的每一行,类似于:
select t.id, t.price,
c.items foreign_id
from yt t
cross apply dbo.split(t.LIST_OF_FOREIGN_IDS, ',') c;
答案 1 :(得分:0)
如果这些是外键ID,那么您有另一个包含所有这些键的表。以下不是一种特别有效的方法,但它避免了必须定义另一个函数。
select t.id, t.price, ft.foreign_id
from t join
foreigntable ft
on ','+LIST_OF_FOREIGN_IDS +',' like '%,'+cast(ft.foreign_id as varchar(255))+',%'
这是使用like
方法查找字符串中的内容。它在每一端都添加了分隔符。搜索“1”实际上是搜索“,1”,因此它与“10”不匹配。
您可以轻松地创建视图:
create myview as
select t.id, t.price, ft.foreign_id
from t join
foreigntable ft
on ','+LIST_OF_FOREIGN_IDS +',' like '%,'+cast(ft.foreign_id as varchar(255))+',%'