使用UNION创建高效查询

时间:2013-12-11 04:45:04

标签: sql sql-server tsql

我正在尝试获取一个国家/地区的所有公民的列表,并将其列在一个包含3行的表中。 最后一行显示“是”或“否”,具体取决于该人是否出生在某个城市。

我所做的是创建两个查询:第一个查询获取在城市出生的所有公民,第二个查询获得所有未在城市出生的公民。

然后我就做了一个UNION。

查询运行,我认为结果看起来不错。

但我想知道,这是形成这样的查询的最佳方法吗?

由于

--all citizens who were born in CityID = 5 who is in the USA
SELECT DISTINCT(CountryCitizenID), Country, 'YES' As Resident
FROM DT_Country_CitizenS dtu
INNER JOIN FT_City fte ON dtu.CountryCitizenID = fte.CitizenID
WHERE cityID = 5
AND Country = 'USA'

UNION

--all Citizens who were not born in CityID = 5 who is in the USA
SELECT  DISTINCT(CountryCitizenID), Country, 'NO' As Resident  
FROM DT_Country_CitizenS dtu 
WHERE NOT EXISTS (
    SELECT CitizenID 
    FROM FT_City fte 
    WHERE  dtu.CountryCitizenID = fte.CitizenID
    AND   cityID = 5)
AND Country = 'USA'

3 个答案:

答案 0 :(得分:5)

你不应该需要UNION(通常,当你有两个不可能相交的查询时,你应该使用UNION ALL来避免独特的排序(或类似的操作) )。此外,DISTINCT无法应用于单个列,因为您当前的查询似乎意味着。我发现CountryCitizenID列中不太可能存在重复项,除非命名真的很差,所以我认为根本不需要DISTINCT。最后,提取Country列的重点是什么,因为根据定义它在每一行都是相同的?我已将其更改为常量而不是拉实际值(这可能会阻止查找或更好地使用skinnier索引),但您根本不需要输出中的该列 - 应用程序应该知道因为WHERE子句只过滤到Country = 'USA'的行,所以没有其他可能的值。

SELECT CountryCitizenID, Country = 'USA', Resident = CASE WHEN EXISTS
(
    SELECT 1
    FROM dbo.FT_City fte 
    WHERE fte.CitizenID = dtu.CountryCitizenID
    AND   fte.cityID = 5
) THEN 'YES' ELSE 'NO' END
FROM dbo.DT_Country_CitizenS AS dtu
WHERE dtu.Country = 'USA';

答案 1 :(得分:2)

试试这个:

SELECT DISTINCT(CountryCitizenID), 
       Country, 
       case when fte.CitizenID is not null then 'YES' else 'NO' As Resident
  FROM DT_Country_CitizenS dtu
    LEFT JOIN (select * 
                 from FT_City 
                where cityID = 5) fte 
         ON (dtu.CountryCitizenID = fte.CitizenID)
 WHERE Country = 'USA'

答案 2 :(得分:1)

SELECT CountryCitizenID, Country, CASE WHEN fte.cityID IS NULL THEN 'No' ELSE 'Yes' END  As Resident
FROM DT_Country_CitizenS dtu
LEFT JOIN FT_City fte 
  ON dtu.CountryCitizenID = fte.CitizenID
  AND fte.cityID = 5
WHERE Country = 'USA'