SQL加入后备

时间:2013-02-11 23:27:31

标签: sql sql-server

给出

CREATE TABLE Addresses
    Id INT NOT NULL
    Zip NVARCHAR(5) NULL    
    ZipPlus4 NVARCHAR(9) NULL

CREATE TABLE ZipLookup
    Zip NVARCHAR(5) NULL    
    Code NVARCHAR(10) NULL

CREATE TABLE ZipPlus4Lookup
    ZipPlus4 NVARCHAR(9) NULL    
    Code NVARCHAR(10) NULL

这样的数据
Addresses
1 | 92123 | 921234444

ZipLookup
92123 | Type A

ZipPlus4Lookup
921234444 | Type B

是否可以构造一个查询:

  • 如果匹配,地址中的给定行外部连接到ZipPlus4Lookup

    Addresses.ZipPlus4 = ZipPlus4Lookup.ZipPlus4

  • 否则,如果匹配,则地址中的给定行外部连接到ZipLookup

    Addresses.Zip = ZipLookup.Zip

  • 否则两个表都不是外连接

简单来说,Addresses表中有一个Zip和一个ZipPlus4列,我需要使用最精确的匹配来查找代码。如果Zip + 4上有匹配项,请使用该匹配项中的代码。否则,请使用Zip匹配中的代码。

我希望我有一个尝试分享的尝试,但有了这个,我不知道从哪里开始。

1 个答案:

答案 0 :(得分:6)

此基本查询将起作用:

SELECT
   A.*,
   Code = IsNull(Z4.Code, Z.Code)
FROM
   dbo.Addresses A
   LEFT JOIN dbo.ZipPlus4Lookup Z4
      ON A.ZipPlus4 = Z4.ZipPlus4
   LEFT JOIN dbo.ZipLookup Z
      ON A.Zip = Z.Zip
      AND Z4.ZipPlus4 IS NULL;

或者您可以尝试这样的事情:

SELECT
   A.*,
   Z.Code
FROM
   dbo.Addresses A
   OUTER APPLY (
      SELECT TOP 1 Code
      FROM (
         SELECT 0, Code FROM dbo.ZipPlus4Lookup Z4
         WHERE A.ZipPlus4 = Z4.ZipPlus4
         UNION ALL
         SELECT 1, Code FROM dbo.ZipLookup Z
         WHERE A.Zip = Z.Zip
      ) X (Seq, Code)
      ORDER BY X.Seq
   ) Z;

它们可能具有不同的性能特征。值得测试。我的猜测是第二个查询是不必要的,但它在概念上仍然可能更好。

在行动in a SQL Fiddle中查看这些内容。