想象一下,您有一個表Products (ID int, Name nvarchar(200))
,以及另外兩個表,ProductsCategories (ProductID int, CategoryID int)
和InvoiceProducts (InvoiceID int, ProductID int)
。複雜的SQL查詢 - 查找與多個不同外鍵匹配的項目
我需要編寫一個查詢來生成一組匹配給定的發票ID和類別ID的產品,以使產品列表匹配所有指定的類別和所有指定的發票,而不會退回到動態SQL 。想象一下,我需要找到類別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)
您是否嘗試過創建臨時表,填充它,然後執行查詢? – BobbyShaftoe 2010-10-25 22:29:37
這看起來像一個非常性感的解決方案給我。你應該添加這個答案。 – 2010-10-27 14:45:39
@mootinator:是的,這也發生在我身上。當臨時表開始看起來很性感時,我知道是時候出去看看一些真正的女孩。 – Quassnoi 2010-10-27 15:00:56