2016-09-16 51 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