【问题标题】:How to get unique values in multiple left join如何在多个左连接中获取唯一值
【发布时间】:2019-09-20 16:34:15
【问题描述】:

我有以下代码,我必须加入 3 个表,但 Dest.Code 有重复值。如何获得 Dest.Code 的唯一值?

我尝试过 DISTINCT 但不起作用。

SELECT
   Dest.Code 
  ,City.CityName  
  ,Country.Id
FROM base.Dest
   Left join base.City
   On base.Dest.CityId = base.City.Id
   Left join base.Country 
   On base.City.CountryId = base.Country.Id

这是结果:但是 ASA 出现了两次。我只需要一次无所谓。

Code    CityName    Id          
ASA     Ardmore     1E-599-4E   
ASA     Miami       8B-203-4D   
WBG     Rome        9S-893-2E   
BMU     Leon        2B-103-8E   

【问题讨论】:

  • 简化您的问题。 (删除一些不需要说明问题的列。)向我们展示一些示例表数据和预期结果 - 全部为格式化文本,没有图像。开始之前先看看minimal reproducible example
  • 您使用的是哪个DBMS 产品? “SQL”只是一种查询语言,而不是特定数据库产品的名称(而且您的查询是无效的标准 SQL)。请为您正在使用的数据库产品添加tag
  • 请提供样本数据和期望的结果。 当有重复时你想要哪个值?
  • 我已经添加了结果。我使用 SQL 服务器。

标签: sql-server filter unique-values


【解决方案1】:

使用新列将您的查询包装在 CTE 中,您将使用该列过滤结果。
这个新列是使用由 Dest.Code 分区的 ROW_NUMBER() 窗口函数生成的:

WITH cte as (
  SELECT Dest.Code, City.CityName, Country.Id,
  ROW_NUMBER() OVER (PARTITION BY Dest.Code ORDER BY City.CityName, Country.Id) AS rn   
  FROM Dest
  LEFT JOIN City ON Dest.CityId = City.Id
  LEFT JOIN Country ON City.CountryId = Country.Id
)
SELECT Code, CityName, Id
FROM cte
WHERE rn = 1

【讨论】:

  • 嘿,谢谢你的回答。我试了一下,得到了这个错误:无法绑定多部分标识符“Dest.Code”。
  • 试试我编辑的答案。我从查询中删除了base.
【解决方案2】:
SELECT
   Dest.Code 
  ,Dest.DestName 
  ,Dest.Code + ' ' + Dest.DestName as Destination
  ,Dest.Latitude
  ,Dest.Longitude
  ,Dest.CityId
  ,City.InternCityName 
  ,City.CityName 
  ,Country.CountryNameInt 
  ,Country.CountryName 
  ,Case 
     when Country.CountryName = 'Country' 
     then 'Local' 
     else 'Exterior' 
     end 
FROM DataBase.Destinations as Dest
INNER JOIN
(
    SELECT  DISTINCT Code,CityId FROM  DataBase.Destinations AS dest1 
)dest2

ON dest.CityId=dest2.CityId

Left join DataBase.Cities City
On Dest.CityId = City.Id

Left join DataBase.Countries Country
On City.CountryId = Country.Id

注意:子查询用于不同的值,内连接用于公共 仅值...

【讨论】:

  • 感谢您的回答,这是有道理的,但是我使用的是 SQL 服务器,它不允许我使用 DISTINCT ON,应该吗?
  • 我没听懂……你想说什么……?
  • DISTINCT 不是函数。它是SELECT DISTINCT 的一部分,适用于整个选定的行。去掉那些多余的括号,直接写SELECT DISTINCT Code, CityId FROM ...,让代码更清晰!
  • 好的。但是当我运行代码时出现错误:关键字'on'附近的语法不正确。
  • 我已经编辑了我的答案......这对你有用......肯定......我错误地在 dest1.CityId=Dest.CityId 这一行上添加了这一行......跨度>
【解决方案3】:

我喜欢将其视为 CTE 或任何使用行号的任何东西的创造性替代方案,但我不知道性能:

SELECT
   Dest.Code 
  ,max(City.CityName + ' ### ' + Country.Id)
FROM base.Dest
   Left join base.City
   On base.Dest.CityId = base.City.Id
   Left join base.Country 
   On base.City.CountryId = base.Country.Id
group by dest.code

这存在将 CityName 和 Country.Id 显示为单个输出列的问题。这可能是可以接受的——或者您可以使用 patindex、left 和 substring 将其拆分出来:

SELECT
   Dest.Code 
  ,left(max(City.CityName + ' ### ' + Country.Id),patindex('% ### %',max(City.CityName + ' ### ' + Country.Id))) CityName
  ,substring(max(City.CityName + ' ### ' + Country.Id),patindex('% ### %',max(City.CityName + ' ### ' + Country.Id)) + 5,len(max(City.CityName + ' ### ' + Country.Id))) Id
FROM base.Dest
   Left join base.City
   On base.Dest.CityId = base.City.Id
   Left join base.Country 
   On base.City.CountryId = base.Country.Id
group by dest.code

它可能会有点混乱/难以理解。此外,必须知道添加在 CityName 和 Country.Id 之间的(任意)字符串在 CITYNAME 中不存在。 最后,我提供的代码没有正确解释任何空值。我会将 City.CityName 和 Country.Id 的每个实例替换为 isnull(City.CityName,'') 和 isnull(Country.Id,'')。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-08-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-12
    • 1970-01-01
    相关资源
    最近更新 更多