2016-09-16 63 views
0

我正在使用SQL SERVER 2014,並且我有這個查詢需要重建以更有效地實現它。如何在同一查詢中有效地查詢同一組列的同一列值

作爲示例,我創建了此模式並向其添加了數據,以便我們可以複製該問題。您可以在rextester嘗試(http://rextester.com/AIYG36293

create table Dogs 
(
    Name nvarchar(20), 
    Owner_ID int, 
    Shelter_ID int 
); 

insert into Dogs values 
('alpha', 1, 1), 
('beta', 2, 1), 
('charlie', 3, 1), 
('beta', 1, 2), 
('alpha', 2, 2), 
('charlie', 3, 2), 
('charlie', 1, 3), 
('beta', 2, 3), 
('alpha', 3, 3); 

我想找出住房擁有這些集的所有者和狗的名字的組合,它必須是準確的。這是我現在使用的查詢(這是產生或多或少何種查詢實體框架但也有一些細微的變化,使其更簡單):

SELECT DISTINCT 
Shelter_ID 
FROM Dogs AS [Extent1] 
WHERE (EXISTS (SELECT 
    1 AS [C1] 
    FROM [Dogs] AS [Extent2] 
    WHERE [Extent1].[Shelter_ID] = [Extent2].[Shelter_ID] AND [Extent2].[Name] = 'charlie' AND [Extent2].[Owner_ID] = 1 
)) AND (EXISTS (SELECT 
    1 AS [C1] 
    FROM [dbo].[Dogs] AS [Extent3] 
    WHERE [Extent1].[Shelter_ID] = [Extent3].[Shelter_ID] AND [Extent3].[Name] = 'beta' AND [Extent3].[Owner_ID] = 2 
)) AND (EXISTS (SELECT 
    1 AS [C1] 
    FROM [dbo].[Dogs] AS [Extent4] 
    WHERE [Extent1].[Shelter_ID] = [Extent4].[Shelter_ID] AND [Extent4].[Name] = 'alpha' AND [Extent4].[Owner_ID] = 3 
)) 

。該查詢能得到我所需要的,但我想知道是否有更簡單的查詢方式。因爲在我的實際使用案例中,我不止有3種組合需要擔心,它可能會達到1000或更多的瘋狂組合。所以,想象一下在那裏有1000個子查詢,好吧,是的,你明白了。當我試着使用許多查詢,我得到一個錯誤說:

查詢處理器用盡了內部資源,無法 生成查詢計劃。這是一件罕見的事情,只有在引用非常大的 數量的表或分區時纔會出現極其複雜的查詢或查詢。

注意 一個解決方案,我試圖用一個Pivot扁平化的數據,雖然查詢變得更加簡單,因爲它會那麼只是一個簡單的WHERE條款與多家AND語句,但是當在某些時候我

無法創建大小10514這是更大的一排:創建我的臨時表時存儲的扁平化數據到組合的一個較大的數字號碼,然後我超過允許的最大行大小的限制,並且得到這個錯誤超過允許的 最大行尺寸爲8060.

我很感激任何關於此事的幫助或想法。

謝謝!

+0

爲什麼[entity-framework]標籤?請注意,您也可以使用OR。 [(a和b)或(c和d)...]。如果查詢太大,請以塊爲單位收集數據。 –

+0

不需要Dog_ID? (狗有時被他們的新主人重新命名) – jarlh

+0

@GertArnold我使用了實體框架並從它生成的查詢中獲得,因此我只是將它添加到標記中。 – Randolph

回答

1

數它們。

WITH dogSet AS (
    SELECT * 
    FROM ( 
     VALUES ('charlie',1),('beta',2),('alpha',3) 
    ) ts(Name,Owner_ID) 
) 
SELECT Shelter_ID 
FROM Dogs AS [Extent1] 
JOIN dogSet ts ON ts.Name= [Extent1].name and ts.Owner_ID = [Extent1].Owner_ID 
GROUP BY Shelter_ID 
HAVING count(*) = (SELECT count(*) n FROM dogSet) 
+0

謝謝,我會嘗試一下,看看它如何與更多的組合。 – Randolph