2010-06-26 86 views
1

问题选择记录,其中分记录是从列表

我试图写一个存储过程来选择NewsItem列表记录其中每个NewsItem拥有所有分类是的在一个列表中。如果列表为空,那么它应该返回所有新闻项目。

NewsItem  NewsItemCategories  Category 
--------  ------------------  -------- 
NewsID  NewsID     CategoryID 
Post   CategoryID    CategoryName 

我通过逗号分隔的类别名称的列表,以我的存储过程,并创建了一个返回这些类别的表中的功能。

exec sp_GetNewsItems 'sport,football,hockey' 

EntityNameColumn - table returned from my function BuildStringTable 
---------------- 
sport 
finance 
history 

我曾尝试

select NI.NewsID, NI.Post 
from NewsItem NI 
where (@pCategories = '' or 
    (select COUNT(*) 
    from NewsItemCategories NIC 
    inner join Category C on NIC.CategoryID = C.CategoryID 
    inner join BuildStringTable(@pCategories) CT on C.CategoryName = CT.EntityNameColumn 
where NIC.NewsID = NI.NewsID) > 0) 

问题

如果你传递一个类别名称的查询工作,但是当你传递多个类别名称不起作用。在上面的示例查询中,这应该返回包含至少至少的NewsItems,Categories运动,足球,曲棍球。

回答

1

如果您使用的是sql 2005或更高版本,则可以使用EXCEPT运算符来查找包含所有必需类别的新闻项目。或者更确切地说,找到在新闻项目类别名称集合中未找到的类别列表中没有名称的新闻项目。

select NI.NewsID, NI.Post 
from NewsItem NI 
where (@pCategories = '' or 
    NOT EXISTS (select EntityNameColumn FROM BuildStringTable(@pCategories) 
     EXCEPT 
       Select CategoryName FROM NewsItem ni 
       join NewsItemCategories nic ON ni.NewsID=nic.NewsID 
       join Category c ON c.CategoryID = nic.CategoryID 
     WHERE ni.NewsID=NI.NewsID)) 

要做到这一点,而不EXCEPT操作是这样的:

where (@pCategories = '' or 
    NOT EXISTS (select EntityNameColumn FROM BuildStringTable(@pCategories) ct 
     LEFT OUTER JOIN 
       (Select CategoryName FROM NewsItem ni 
       join NewsItemCategories nic ON ni.NewsID=nic.NewsID 
       join Category c ON c.CategoryID = nic.CategoryID 
       WHERE ni.NewsID=NI.NewsID) nicn 
     WHERE nicn.CategoryName IS NULL)