3

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 |

有人知道从第二个表中获取数据的解决方案吗?

4

2 回答 2

6

如果可能,您需要在此表上修复您的数据库设计,这样您就不会存储逗号分隔的值列表。这将很难维护。

理想情况下,您的表结构可以更改如下:

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;

请参阅带有演示的 SQL Fiddle

于 2013-06-03T21:01:39.403 回答
0

如果这些是外键 ID,那么您将拥有另一个包含所有这些 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))+',%'
于 2013-06-03T21:08:28.810 回答