Выберите записи, где вложенные записи из списка - PullRequest
1 голос
/ 26 июня 2010

Проблема

Я пытаюсь написать хранимую процедуру для выбора списка 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, которые содержат не менее , Категории спорт, футбол, хоккей.

1 Ответ

1 голос
/ 26 июня 2010

Если вы используете 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)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...