SQL减少了union子句中的重复项

时间:2014-10-10 17:12:20

标签: sql oracle

让我们说例如我有以下查询:

SELECT City, Country FROM Customers
WHERE Country='Germany'
UNION
SELECT City, Country FROM Suppliers
WHERE Country='Germany'
ORDER BY City;

正如您所看到的,WHERE Country='Germany'在联盟的两个目标中都重复了 - 有没有办法将其减少到一个查询而不重复?我不喜欢我的查询太长。

我目前正在研究Oracle。

6 个答案:

答案 0 :(得分:2)

select distinct city, country
from
(
   SELECT City, Country FROM Customers
   WHERE Country='Germany'
   UNION ALL
   SELECT City, Country FROM Suppliers
   WHERE Country='Germany'
) x
order by city

如果你真的想要两组行,你真的无法满足UNION的需求:我在主SQL中加了一个UNION ALL而在外面加了DISTINCT删除重复但没有额外的排序操作(假设你想这样做)。

答案 1 :(得分:2)

SELECT * FROM
(
    SELECT City, Country FROM Customers
    UNION
    SELECT City, Country FROM Suppliers
) t
WHERE t.Country='Germany'
ORDER BY t.City;

答案 2 :(得分:2)

为什么不将WHERE仅包括一次

SELECT * FROM
(
SELECT City, Country FROM Customers
UNION ALL
SELECT City, Country FROM Suppliers
ORDER BY City
) tab 
WHERE Country='Germany'

(或)做JOIN之类的

SELECT c.City as CustomerCity, c.Country as customerCountry, 
s.City as suppliercity, s.Country as suppliercountry
FROM Customers c
LEFT JOIN Suppliers s ON c.Country = s.Country
AND c.Country='Germany'
ORDER BY c.City;

答案 3 :(得分:2)

您已经拥有的代码非常紧凑和清晰,同时不会牺牲性能。

使用子查询的建议可以消除重复的WHERE语句,但是比最初提供的简单联合需要更多的i / o活动。 当子查询中有一个联合,然后在它外面有一个WHERE时,这就要求SQL引擎构建一个临时表,该表是customer表中添加到供应商表中所有行的所有行,然后查询结果表扔出不是country = Germany的行。如果您的表只有几百行并且您在本地运行查询,则可能不会显示太多性能差异,但如果您在网络上的不同服务器上有数千个行或表,则性能可能会慢几个数量级

如果考虑性能,可以通过使用国家/地区的变量来使查询更简单,更易于维护:

VAR country varchar2(64);
EXEC :country := 'Germany';

SELECT City, Country FROM Customers
WHERE Country=' :country
UNION
SELECT City, Country FROM Suppliers
WHERE Country= :country
ORDER BY City; 

这显然不会缩短代码,但它更简洁,更易于修改,只检索您感兴趣的行,从而提供更好的性能。

答案 4 :(得分:1)

您可以使用公用表表达式(CTE):

WITH CTE AS (
    SELECT City, Country FROM Customers
    UNION
    SELECT City, Country FROM Suppliers)
SELECT  City, Country  
FROM CTE
WHERE CTE.Country='Germany'
ORDER BY CTE.City;

我发现它比嵌套的子查询更容易阅读。

答案 5 :(得分:0)

同意帕特里克。查询性能比查询长度重要得多。提到的所有替代解决方案的性能都比原始解决方案慢。