如何有效地在同一查询中查询具有不同值集的同一组列

时间:2016-09-16 07:41:14

标签: sql sql-server-2014

我正在使用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);

我想找出哪些 Shelter 具有这些所有者和狗名称组合,并且必须准确无误。这是我现在正在使用的查询(这或多或少是查询实体框架生成的,但稍微进行了一些改动以使其更简单):

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。

感谢您对此事的任何帮助或想法。

谢谢!

1 个答案:

答案 0 :(得分: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)