根据多个条件和优先级SQL连接两个表

问题描述

我正在尝试将两个表连接在一起,这些表将根据城市和邮政编码返回区域的分类

表A包含有关客户及其位置的信息

Table A

表B包含有关郊区,邮政编码和区域分类的信息

Table B

我想按优先顺序匹配两个表:

  1. 郊区和邮政编码
  2. 邮政编码
  3. 郊区

我很难加入两个表。我有代码,到目前为止,它仅与第一个首选项匹配。如果邮政编码OR郊区为NULL,则分类返回NULL。

SELECT 
A.*,B.Classification 
INTO NEWTABLE 
FROM TABLEA AS A 
   LEFT JOIN TABLEB AS B
      ON A.City = B.City
      AND A.Postcode = B.Postcode

我认为解决方案非常简单,但是我无法理解sql语言。我正在使用Microsoft sql。非常感谢!

解决方法

这是使用横向连接的好地方-OUTER APPLY,在这种情况下:

SELECT A.*,B.Classification 
INTO NEWTABLE 
FROM TABLEA A OUTER APPLY
     (SELECT TOP (1) B.*
      FROM ((SELECT B.*
             FROM TABLEB B
             WHERE A.City = B.City 
            ) UNION ALL
            (SELECT B.*
             FROM TABLEB B
             WHERE A.Postcode = B.Postcode AND (A.City <> B.City OR B.City IS NULL)
            )
           ) B
      ORDER BY ((CASE WHEN B.PostCode = A.PostCode THEN 2 ELSE 0 END) +
                (CASE WHEN B.City = A.PostCode THEN 1 ELSE 0 END)
               ) DESC
     );

这是结构化的,因此查询可以利用B(Postcode)B(City)上的索引。

假设邮编和城市匹配意味着 other 列为NULL,那么您也可以使用LEFT JOIN s来做到这一点:

SELECT A.*,COALESCE(BCP.Classification,BP.Classification,BC.Classification) as Classification
INTO NEWTABLE 
FROM TABLEA AS A LEFT JOIN
     TABLEB  BCP
     ON BCP.City = A.City AND
        BCP.Postcode = A.Postcode LEFT JOIN
     TABLEB BP
     ON BP.Postcode = A.Postcode AND
        BP.City IS NULL AND
        BCP.City IS NULL LEFT JOIN  -- no match above
     TABLEB BC
     ON BC.City = A.City AND
        BC.PostCode IS NULL AND
        BP.PostCode IS NULL;

此结构经过精心设计,可避免重复行。

,

一种方法是LEFT JOIN 3次相同的表并使用COALESCE

SELECT A.*,COALESCE(B1.Classification,B2.Classification,B3.Classification) as Classification
INTO NEWTABLE 
FROM TABLEA AS A 
LEFT JOIN TABLEB AS B1
      ON A.City = B1.City
      AND A.Postcode = B1.Postcode
LEFT JOIN TABLEB AS B2
      ON A.Postcode = B2.Postcode
LEFT JOIN TABLEB AS B3
      ON A.City = B3.City