我正在尝试获取一个国家/地区的所有公民的列表,并将其列在一个包含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'
答案 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'