2012-08-10 81 views
-1

请考虑以下查询,其中两个集合需要被相同的Location过滤。是否有更高效的/高效的方法,因此Location筛选器仅在两个套件中应用一次,或者您是否被迫分别对每个套件应用相同的筛选器?SQL集合操作中的WHERE子句

SELECT * 
FROM Orders 
WHERE Quantity BETWEEN 1 AND 100 
AND Location = 'SE' 

EXCEPT 

SELECT * 
FROM Orders 
WHERE Quantity BETWEEN 50 AND 75 
AND Location = 'SE'; 

注:并不想重构组操作每SE-它只是一个虚拟的例子。我的问题只是关于如何在集合操作中处理常用的WHERE子句。

回答

1

您可以用CTE做到这一点:

with ord (Column1, Column2) as 
(
    SELECT Column1, Column2 
    FROM Orders 
    WHERE Location = 'SE' 
) 
SELECT * 
FROM ord 
WHERE Quantity BETWEEN 1 AND 100 

EXCEPT 

SELECT * 
FROM ord 
WHERE Quantity BETWEEN 50 AND 75 

如果热膨胀系数不到位,你可以做同样的事情用视图。

+0

在列部分不清晰 - 这是否会使我的结果并排? – Yarin 2012-08-10 02:47:21

+0

使用CTE时,必须明确命名列而不是使用'*'。这就是'Column1'和'Column2'表示的地方,因为你没有提供模式。 – RedFilter 2012-08-10 02:50:26

+0

啊 - 明白了。好吧,这可能是什么后 – Yarin 2012-08-10 02:50:55

4

我会重新因素的查询简单:

SELECT * 
FROM Orders 
WHERE Quantity BETWEEN 1 AND 100 
AND Quantity NOT BETWEEN 50 AND 75 
AND Location = 'SE'; 
+0

不,我需要单独的集合操作 - 我只是在常见的过滤器(代码粘贴来自维基百科设置的例子 - 我不需要重构的实际集合)感兴趣 – Yarin 2012-08-10 02:35:53

+0

@Yarin你会做得更好发布您需要帮助的查询,而不是错误地表示您的情况。 – RedFilter 2012-08-10 02:38:17

0
SELECT * 
FROM Orders 
WHERE ((Quantity BETWEEN 1 AND 49) OR (Quantity BETWEEN 76 AND 100)) 
AND Location = 'SE' 

试试这个查询,并确保它取得相同的结果。

0

我会做这种方式:

SELECT * 
FROM Orders 
WHERE ((Quantity BETWEEN 1 AND 49) 
OR (Quantity BETWEEN 76 AND 100)) 
AND Location = 'SE'; 
+0

这个逻辑是不正确的 - 记住'BETWEEN'是包含性的。 – RedFilter 2012-08-10 02:40:02

+0

@RedFilter忘了这一点,谢谢。编辑。 – 2012-08-10 02:51:10

+0

现在你正在复制@sundar已经给出的答案。不确定这有多大价值。 – RedFilter 2012-08-10 02:52:18

-1
SELECT * 
FROM Orders o1 
WHERE Quantity BETWEEN 1 AND 100 
AND Location = 'SE' 
AND NOT EXISTS (SELECT 1 FROM ORDERS o2 
       WHERE QUANTITY BETWEEN 50 AND 75 
       AND Location = 'SE' 
       AND o1.ORDERS_ID = o2.ORDERS_ID) 
+0

从这个问题:*是否有一个更有效率/性能的方法,即位置过滤器**仅在两个集合上应用一次** * – RedFilter 2012-08-10 02:40:51

1

您可以使用AND NOT而不是EXCEPT来处理设置的操作,并在不同平台上提供更大的支持。

我认为有些事情值得一提,一个总结:

  1. 将最有可能表达第一。
  2. 先放最少复杂的表情。
  3. 使用更多和更少的搜索。

反向点1 & 2如果您使用Oracle,则由于从右到左评估而不是从左到右。

+0

Lau-你能扩展3吗? – Yarin 2012-08-10 03:03:10

+0

@Yarin:第3点我指的是使用比较运算符(例如>,<,==)而不是逻辑运算符(例如ANY,BETWEEN,EXIST)。这是由于比较操作涉及单索引搜索,而一些逻辑操作涉及多索引搜索。一个例子(虽然可能不是确切的)可以在这里找到(http://www.devx.com/dbzone/Article/36339/1954) – 2012-08-10 03:19:37

+0

谢谢 - 一些好点 – Yarin 2012-08-10 03:22:55