ISNULL/COALESCE用于多个领域

Tel*_*ini 1 t-sql sql-server join coalesce

考虑以下数据模型:

顾客

CustNum | First Name | Last Name
  555        John         Doe
Run Code Online (Sandbox Code Playgroud)

CustomerAddresses

CustNum | ShippingAddress|     Line1      |  Line2  |   City  | State |  Zip    
  555   |     ADD1       |   333 A Dr.    | Apt. 10 | Dallas  |  TX   | 11345  
  555   |     ADD2       |   111 B St.    |  NULL   | Miami   |  FL   | 22222
  555   |     WXYZ       |  123 Main St.  |  NULL   | Detroit |  MI   | 99998
Run Code Online (Sandbox Code Playgroud)

OrderHeader

OrdNum | CustNum | OrderTotal |     Line1     | Line2 |   City  | State|  Zip
 1000  |   555   |   67.00    | 123 Main St.  | Ste 1 | Detroit |  MI  | 99998
Run Code Online (Sandbox Code Playgroud)

订单行

OrderNo  | Item  |  Price  | ShippingAddress  
 1000    | X123  |  32.00  |     ADD1
 1000    | Y234  |  25.00  |     ADD2
 1000    | ZZZZ  |  10.00  |     NULL  
Run Code Online (Sandbox Code Playgroud)

客户和CustomerAddresses之间存在一对多的关系.
每个OrderHeader,而不是与CustomerAddresses表的关键关系,存储在Line1,Line2,City,State和Zip字段中用于运送的地址.
此外,可以在OrderLine表中选择一个覆盖OrderHeader中存储的地址的送货地址.
我正在尝试用以下格式返回数据的查询,以生成邮件标签列表:
MailingLabels

OrderNo  | Item  |     Line1      |  Line2  |   City  | State |  Zip     
 1000    | X123  |   333 A Dr.    | Apt. 10 | Dallas  |  TX   | 11345
 1000    | Y234  |   111 B St.    |  NULL   | Miami   |  FL   | 22222
 1000    | ZZZZ  |  123 Main St.  |  NULL   | Detroit |  MI   | 99998   
Run Code Online (Sandbox Code Playgroud)

基本上,如果OrderLine记录具有ShippingAddress值,我想从CustomerAddresses表返回相应的地址.
如果它为NULL,那么我想返回存储在OrderHeader表中的Line1,Line2,City,State和Zip值.
问题是,当我使用COALESCE或ISNULL时,可能会返回不正确的结果.这是我的查询:

SELECT OH.OrderNo, Item, ISNULL(CA.Line1, OH.Line1), ISNULL(CA.Line2, OH.Line2),  
       ISNULL(CA.City, OH.City), ISNULL(CA.State, OH.State), ISNULL(CA.Zip, OH.Zip)
FROM   OrderHeader OH
JOIN   OrderLine OL
ON     OH.OrderNo = OL.OrderNo
LEFT JOIN   CustomerAddress CA
ON     OL.CustNum = CA.CustNum
AND    OL.ShippingAddress = CA.ShippingAddress  
Run Code Online (Sandbox Code Playgroud)

使用上述查询,如果为OrderHeader定义了Line2字段,但在OrderLine中定义了ShippingAddress,则可以返回Y234项的混合地址:

OrderNo | Item |   Line1   |  Line2  |   City  | State |  Zip            
1000    | Y234 | 111 B St. |  Ste 1  |  Miami  |  FL   | 22222  
Run Code Online (Sandbox Code Playgroud)

注意,Ste 1不是OrderLine中表示的地址的一部分,它实际上是OrderHeader的一部分.
如何编写查询以按所需方式返回数据?非常感谢任何和所有的帮助!

Dam*_*ver 6

不幸的是,我不能想到一个简洁的方法来做到这一点,而不是重复.

假设OL别名应该是CA:

SELECT OH.OrderNo, Item,
       CASE WHEN OL.ShippingAddress IS NULL THEN OH.Line1 ELSE CA.Line1 END,
       CASE WHEN OL.ShippingAddress IS NULL THEN OH.Line2 ELSE CA.Line2 END,
       CASE WHEN OL.ShippingAddress IS NULL THEN OH.City ELSE CA.City END,
       CASE WHEN OL.ShippingAddress IS NULL THEN OH.State ELSE CA.State END,
       CASE WHEN OL.ShippingAddress IS NULL THEN OH.Zip ELSE CA.Zip END
FROM   OrderHeader OH
JOIN   OrderLine OL
ON     OH.OrderNo = OL.OrderNo
LEFT JOIN   CustomerAddress CA
ON     OL.CustNum = CA.CustNum
AND    OL.ShippingAddress = CA.ShippingAddress
Run Code Online (Sandbox Code Playgroud)