したがって、のテーブルProducts (ID int, Name nvarchar(200))
と他の2つのテーブル、ProductsCategories (ProductID int, CategoryID int)
およびがあると想像してくださいInvoiceProducts (InvoiceID int, ProductID int)
。
動的SQLにフォールバックせずに、製品のリストが指定されたすべてのカテゴリとすべての指定された請求書に一致するように、特定の請求書IDとカテゴリIDのセットに一致する製品のセットを生成するクエリを作成する必要があります。カテゴリ1と2、および請求書3と4の両方にある製品のリストを見つける必要があると想像してください。
まず、カテゴリIDと請求書IDを文字列として受け入れ、それらをテーブルに解析するストアドプロシージャを作成しました。
CREATE PROCEDURE dbo.SearchProducts (@categories varchar(max), @invoices varchar(max))
AS BEGIN
with catids as (select cast([value] as int) from dbo.split(@categories, ' ')),
invoiceids as (select cast([value] as int) from dbo.split(@invoices, ' '))
select * from products --- insert awesomeness here
END
私が思いついたさまざまなソリューションはひどく見え、パフォーマンスが低下します。私が見つけた最良のことは、すべての基準の左結合で構成されるビューを生成することですが、これは非常にコストがかかるようで、指定されたすべての異なるキーの一致の問題を解決しません。
更新: これは私が書いたクエリの例で、期待される結果が得られます。最適化の機会を逃していますか?忍者による魔法のユニコーンマトリックス操作のように?
with catids as (select distinct cast([value] as int) [value] from dbo.split(@categories, ' ')),
invoiceids as (select distinct cast([value] as int) [value] from dbo.split(@invoices, ' '))
select pc.ProductID from ProductsCategories pc (nolock)
inner join catids c on c.value = pc.CategoryID
group by pc.ProductID
having COUNT(*) = (select COUNT(*) from catids)
intersect
select ip.ProductID from InvoiceProducts ip (nolock)
inner join invoiceids i on i.value = ip.InvoiceID
group by ip.ProductID
having COUNT(*) = (select COUNT(*) from invoiceids)