2010-06-26 3 views
1

ProblèmeSélectionnez les enregistrements où les enregistrements de sous sont une liste

Je suis en train d'écrire une procédure stockée pour sélectionner une liste de NewsItem dossiers où chaque NewsItem a toutes les Catégories qui sont dans une liste. Si la liste est vide, elle doit renvoyer tous les éléments d'actualité.

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

Je passe une liste des noms des catégories séparées par des virgules à ma procédure stockée et ont créé une fonction qui retourne une table de ces catégories.

exec sp_GetNewsItems 'sport,football,hockey' 

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

Ce que j'ai essayé

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) 

Question

La requête fonctionne si vous passez un seul nom de la catégorie, cependant ne fonctionne pas lorsque vous passez plusieurs noms de catégorie. Dans l'exemple de requête ci-dessus, il faut retourner les articles de News qui contiennent, au moins, Catégories sport, football, hockey.

Répondre

1

Si vous utilisez sql 2005 ou plus récent, vous pouvez utiliser l'opérateur EXCEPT pour rechercher les actualités contenant toutes les catégories requises. Ou plus précisément, recherchez les articles d'actualité dans lesquels aucun nom ne figure dans la liste des catégories qui ne figuraient pas dans l'ensemble des noms de catégories d'articles.

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)) 

Pour ce faire, sans EXCEPT ressemble à ceci:

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) 
Questions connexes