让我们说例如我有以下查询:
SELECT City, Country FROM Customers
WHERE Country='Germany'
UNION
SELECT City, Country FROM Suppliers
WHERE Country='Germany'
ORDER BY City;
正如您所看到的,WHERE Country='Germany'
在联盟的两个目标中都重复了 - 有没有办法将其减少到一个查询而不重复?我不喜欢我的查询太长。
我目前正在研究Oracle。
答案 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)
同意帕特里克。查询性能比查询长度重要得多。提到的所有替代解决方案的性能都比原始解决方案慢。