2010-06-26 88 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)