【问题标题】:SQL JOIN on multiple possibilitiesSQL JOIN 关于多种可能性
【发布时间】:2017-01-16 22:28:56
【问题描述】:

我有一个奇怪的问题要问。我有两个具有多对多关系的表,所以中间有一个桥接表。桥接表现在由以下人员填充:

select
    P.RTPropertyUniqueIdentifier
    , P.ParcelID
    , M.Assessors_Parcel_Identification_Number
    , M.FA_Unique_Listing_Identifier_Ref_ID
    , M.Property_Type
    , M.Property_Address
    , P.AddUnitNum
    , 0 as multiple_flag
    into PP_MLS_BRIDGE
FROM MLS M
join PROPERTY_PARAMETERS P on
    replace(replace(M.Assessors_Parcel_Identification_Number, ' ', ''), '.', '') = P.ParcelID;

这是我的问题。

连接字段为Assessors_Parcel_Identification_NumberParcelID。一张表中有超过 1.8 亿条记录,另一张表中有 2000 万条记录。我的问题是这两者可以匹配的方式不止一种:

  1. Assessors_Parcel_Identification_Number = ParcelID
  2. replace(replace(M.Assessors_Parcel_Identification_Number, ' ', ''), '.', '') = ParcelID
  3. replace(replace(replace(M.Assessors_Parcel_Identification_Number, ' ', ''), '.', ''), '_', '') = ParcelID

未来可能还会有更多。

问题是如果我执行join on OR 情况,它的笛卡尔答案。我需要在任何一个条件下进行一对一的加入。如何重组它以便扫描一次,如果在任何条件下存在连接,它就是连接?

谢谢。 .

【问题讨论】:

  • 您在寻找与技术无关的解决方案吗?我已经使用 SQL Server 使用 ROW_NUMBER 解决了类似的问题;按主键对结果进行分区,然后按行号选择第一个结果。不过,对于 2000 万个结果,您可能需要一种不同的方法。
  • 不清楚 - 表是否可以有效地加入,比如这些表示中的 2 个?或者这是一个数据清理练习?我建议您添加一个列(计算或批量加载)来计算正确的连接值,然后只连接该列(另一个优点是您可以索引它)
  • 我认为这样的情况是不可维护的。我会在MLS 表中添加一个名为ParcelId 的列,尽我所能将所有现有的Assessors_Parcel_Identification_Number 转换为有效的ParcelID,并在插入时检查匹配。
  • 我可以看到列的东西,但我仍然会遇到匹配字段的问题。它可能是基于 3 种可能方法中的一种的匹配,这一事实仍然存在。
  • @Nick.McDermaid 我试图通过尽可能多的匹配将这两个表连接在一起。比赛结果进入桥牌表。我在这里遇到的问题是三个可能关联的连接条件。

标签: sql-server join


【解决方案1】:

我认为解决此问题的两种方法是:

首先,您需要确定它尝试加入的顺序。然后,您需要确定使用 join 的逻辑。最后,在连接的 case 语句中应用该逻辑。

我假设提供的任何连接都不能 100% 使用,并且在生成的连接中应该是相同的。

    JOIN PROPERTY_PARAMETERS P ON
    ParcelID = CASE
        WHEN Assessors_Parcel_Identification_Number IS NOT NULL THEN Assessors_Parcel_Identification_Number 
        WHEN TRY_CAST(replace(replace(M.Assessors_Parcel_Identification_Number, ' ', ''), '.', '') AS INT) IS NOT NULL THEN TRY_CAST(replace(replace(M.Assessors_Parcel_Identification_Number, ' ', ''), '.', '') AS INT) = ParcelID
        WHEN TRY_CAST(replace(replace(replace(M.Assessors_Parcel_Identification_Number, ' ', ''), '.', ''), '_', '') AS INT) IS NOT NULL THEN TRY_CAST(replace(replace(replace(M.Assessors_Parcel_Identification_Number, ' ', ''), '.', ''), '_', '') AS INT) = ParcelID
        END

另一种选择是加入表 3 次,每次可用的加入一次。然后你可以 isnull(isnull(resulta,resultb),resultc)。

无论如何,这些都不是理想的解决方案,无法在这么大的表中很好地扩展。理想的解决方案是清理数据以提供您可以使用的单个列标识符。

【讨论】:

  • 好的。我尝试了你的建议..我遇到了内存不足异常错误。
  • 您可以尝试在服务器上运行它,但查询会占用您所有的本地内存,并且可能会根据资源影响服务器。是否有可能清理数据以提供单个列标识符?如果没有,您可以尝试测试它限制结果集。
  • 好的。我一直在尝试设置一个专栏,但我不知道该放什么。当我不知道连接需要什么时,我怎么知道需要在那里进行哪些转换? (三种可能)?谢谢
猜你喜欢
  • 2015-07-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-11-15
  • 1970-01-01
  • 2023-03-17
  • 2012-03-04
相关资源
最近更新 更多