简体   繁体   English

SQL:如何在联接中使用CASE

[英]SQL: How to use CASE in join

Here is the code I am trying to use 这是我正在尝试使用的代码

SELECT
  TData.dtContractDate,
  TData.chPurchase,
  TData.nShipperID,
  TData.nSourceSiteId,
  Vendor.chShipperName,
  Vendor.chCity,
  Vendor.chState,
  Vendor.chCountry,
  Vendor.chZip 
FROM Data1.dbo.TData TData
JOIN Data1.dbo.Vendor
  ON Vendor.nShipperId = TData.nShipperID
  AND Vendor.nCompanyCode  = (CASE WHEN Vendor.nCompanyCode = '2' THEN '2' ELSE '26' END)
WHERE (TData.nCompanyCode=2) AND (TData.dtContractDate > '" 04/23/2015 12:01:00 AM')

I am trying to join these two tables, but if 我正在尝试加入这两个表,但是如果

ncompanycode = 2 AND Vendor.nShipperId = TData.nShipperID , ncompanycode = 2 AND Vendor.nShipperId = TData.nShipperID

then I want to pull that data, if this doesn't exist, then I want to use 那我想拉那些数据,如果这个不存在,那我想用

ncompanycode = 26 and Vendor.nShipperId = TData.nShipperID . ncompanycode = 26 and Vendor.nShipperId = TData.nShipperID

Right now I get duplicates for any shipperID that both companies have. 现在,我得到了两家公司拥有的所有shipperID副本。

Here are the dummy tables and the results I am getting, I don't want duplicates for chPurchase. 这是虚拟表以及我得到的结果,我不希望chPurchase重复。

TData Table TData表

|            dtContractDate | chPurchase | nShipperID | nSourceSiteId | nCompanyCode |
|---------------------------|------------|------------|---------------|--------------|
| January, 04 2015 00:00:00 |    2547635 |        453 |      68686868 |            2 |
| January, 05 2015 00:00:00 |    2547636 |        453 |      68686868 |            2 |
| January, 06 2015 00:00:00 |    2547637 |        454 |      68686868 |            2 |
| January, 07 2015 00:00:00 |    2547638 |        454 |      68686868 |            2 |
| January, 08 2015 00:00:00 |    2547639 |        455 |      68686868 |            2 |
| January, 09 2015 00:00:00 |    2547640 |        456 |      68686868 |            2 |

Vendor Table 供应商表

| nCompanyCode | nShipperID | chShipperName | chCity | chState | chCountry |  chZip |
|--------------|------------|---------------|--------|---------|-----------|--------|
|            2 |        453 |         Name1 | Dallas |      TX |        US | 666555 |
|           26 |        453 |         Name2 | Dallas |      TX |        US | 666556 |
|            2 |        454 |         Name3 | Dallas |      TX |        US | 666557 |
|           26 |        455 |         Name4 | Dallas |      TX |        US | 666558 |
|            2 |        455 |         Name5 | Dallas |      TX |        US | 666559 |
|           26 |        456 |         Name6 | Dallas |      TX |        US | 666560 |

Results Table 结果表

|   dtContractDate | chPurchase | nShipperID | nSourceSiteId | nCompanyCode | chShipperName | chCity | chState | chCountry |  chZip |
|------------------|------------|------------|---------------|--------------|---------------|--------|---------|-----------|--------|
| January, 04 2015 |    2547635 |        453 |      68686868 |           26 |         Name2 | Dallas |      TX |        US | 666555 |
| January, 04 2015 |    2547635 |        453 |      68686868 |            2 |         Name1 | Dallas |      TX |        US | 666555 |
| January, 05 2015 |    2547636 |        453 |      68686868 |           26 |         Name1 | Dallas |      TX |        US | 666556 |
| January, 05 2015 |    2547636 |        453 |      68686868 |            2 |         Name2 | Dallas |      TX |        US | 666556 |
| January, 06 2015 |    2547637 |        454 |      68686868 |            2 |         Name3 | Dallas |      TX |        US | 666557 |
| January, 07 2015 |    2547638 |        454 |      68686868 |            2 |         Name3 | Dallas |      TX |        US | 666558 |
| January, 08 2015 |    2547639 |        455 |      68686868 |            2 |         Name5 | Dallas |      TX |        US | 666559 |
| January, 08 2015 |    2547639 |        455 |      68686868 |           26 |         Name5 | Dallas |      TX |        US | 666559 |
| January, 09 2015 |    2547640 |        456 |      68686868 |            26 |         Name6 | Dallas |      TX |        US | 666560 |

This solution does not use CASE but produces the desired result with cleaner conditionals using COALESCE . 此解决方案不使用CASE但使用COALESCE在更干净的条件下产生期望的结果。

I have shortened your table aliases for readability. 为了缩短可读性,我已经缩短了表别名。

I have also commented out the WHERE clause involving dates because: 我还注释了涉及日期的WHERE子句,因为:

  1. It was mal-formed and would not match any date with current typos. 格式不正确,不会与当前错别字匹配任何日期。
  2. When typos were corrected, it eliminates all rows from your sample data. 纠正错别字后,它将消除样本数据中的所有行。

The SQL code uses two LEFT JOINs and uses COALESCE to choose which one to use in the SELECT output. SQL代码使用两个LEFT JOINs并使用COALESCE选择在SELECT输出中使用哪个。 When the first JOIN ( V ) has a NULL result, the output resorts to V2 . 当第一个JOINV )结果为NULL ,输出求助于V2 The V2 JOIN explicitly requires that the nCompanyCode be 26 , but any criteria can be added or removed as desired if there are multiple alternative nCompanyCodes . V2 JOIN明确要求nCompanyCode26 ,但是如果存在多个替代nCompanyCodes则可以根据需要添加或删除任何条件。

Query: 查询:

SELECT
   T.dtContractDate
  ,T.chPurchase
  ,T.nShipperID
  ,T.nSourceSiteId
  ,COALESCE(V.chShipperName,V2.chShipperName) chShipperName
  ,COALESCE(V.chCity,V2.chCity) chCity
  ,COALESCE(V.chState, V2.chState) chState
  ,COALESCE(V.chCountry,V2.chCountry) chCountry
  ,COALESCE(V.chZip,V2.chZip) chZip
  -- Added to show what Vendor company code is being used
  ,COALESCE(V.nCompanyCode,V2.nCompanyCode) nCompanyCode
FROM TData T
LEFT JOIN Vendor V
  ON V.nShipperId = T.nShipperID
  AND V.nCompanyCode = T.nCompanyCode
LEFT JOIN Vendor V2
  ON V2.nShipperId = T.nShipperID
  AND V2.nCompanyCode <> T.nCompanyCode
  AND V2.nCompanyCode = 26
-- Commented out this WHERE clause because it eliminates all rows
-- WHERE T.dtContractDate > '04/23/2015 12:01:00 AM'

Sample Output: 样本输出:

|   dtContractDate | chPurchase | nShipperID | nSourceSiteId | chShipperName | chCity | chState | chCountry |  chZip | nCompanyCode |
|------------------|------------|------------|---------------|---------------|--------|---------|-----------|--------|--------------|
| January, 04 2015 |    2547635 |        453 |      68686868 |         Name1 | Dallas |      TX |        US | 666555 |            2 |
| January, 05 2015 |    2547636 |        453 |      68686868 |         Name1 | Dallas |      TX |        US | 666555 |            2 |
| January, 06 2015 |    2547637 |        454 |      68686868 |         Name3 | Dallas |      TX |        US | 666557 |            2 |
| January, 07 2015 |    2547638 |        454 |      68686868 |         Name3 | Dallas |      TX |        US | 666557 |            2 |
| January, 08 2015 |    2547639 |        455 |      68686868 |         Name5 | Dallas |      TX |        US | 666559 |            2 |
| January, 09 2015 |    2547640 |        456 |      68686868 |         Name6 | Dallas |      TX |        US | 666560 |           26 |

You can play with the SQLFiddle for this example here . 你可以用SQLFiddle在这个例子中发挥这里

I think what you want is to join on the two tables where the shipper IDs are equal and then select all the rows from that set where the company code is equal to the value you want. 我认为您想要的是将两个托运人ID相等的表连接起来,然后从该集合中选择公司代码等于您想要的值的所有行。 Also, it seems like you don't want that WHERE (TData.nCompanyCode=2) condition, since you're already trying to select where the company code is 2 OR 26 above. 另外,似乎您不希望WHERE (TData.nCompanyCode=2)条件,因为您已经在尝试选择公司代码在2或26以上的位置。 Try this: 尝试这个:

SELECT TData.dtContractDate, TData.chPurchase, TData.nShipperID, 
TData.nSourceSiteId,  Vendor.chShipperName, Vendor.chCity,     
Vendor.chState,  Vendor.chCountry, Vendor.chZip 
FROM Data1.dbo.TData TData
Join Data1.dbo.Vendor on Vendor.nShipperId = TData.nShipperID
WHERE Vendor.nCompanyCode  = (case when Vendor.nCompanyCode = '2' then     
'2' else '26' end)
AND (TData.dtContractDate > '" 04/23/2015     
12:01:00 AM')

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM