SQL多列左连接返回部分匹配

问题描述 投票:0回答:1

我们目前对我们的数据使用查找表的LEFT JOIN来做验证,这些都是在单表对单列,只是对一张表进行正常的左联接,然后我们在SELECT中做一个case语句,说如果返回的值大于0(不是null),那么就可以,否则警告。流程目前是下面的样子。

SELECT

CASE WHEN LEN(C_Market.MCode) > 0 THEN 'Ok' ELSE 'Warning' END AS C_Market
CASE WHEN LEN(C_Language.LCode) > 0 THEN 'Ok' ELSE 'Warning' END AS C_Language

FROM [dbo].[CTable]

LEFT JOIN [dbo].[Lookup_Market] AS C_Market ON [dbo].CTable.[campaignNameMarket] = C_Market.MCode
LEFT JOIN [dbo].[Lookup_Language] AS C_Language ON [dbo].CTable.[campaignNameLanguage] = C_Language.LCode

我们要做的是在多列中进行验证 所以在LEFT JOIN语句中增加一个AND。这将基于映射的查找表。我们的问题是,如果其中一列不匹配,它会将LEFT JOINAND中的所有列返回为NULL(这是有道理的)。是否有一种方法可以进行多重连接,但如果在LEFT JOINAND语句中与该列匹配,则仍然返回值,但只对不匹配的列返回NULL?任何帮助将是非常感激的

例子:请看下面的LookupMap_MarketLanguage表的例子。

SELECT

CASE WHEN LEN(C_MarketLanguage.LCode) > 0 THEN 'Ok' ELSE 'Warning' END AS C_Language,
CASE WHEN LEN(C_MarketLanguage.MCode) > 0 THEN 'Ok' ELSE 'Warning' END AS C_Market

FROM [dbo].[CTable]

LEFT JOIN [dbo].[LookupMap_MarketLanguage] AS C_MarketLanguage ON [dbo].CTable.[campaignNameMarket] = C_MarketLanguage.MCode
AND [dbo].CTable.campaignNameLanguage = C_MarketLanguage.LCode

请看下面LookupMap_MarketLanguage表的例子。这里我们将在MCode和LCode上做一个左连接。比如说,主表的市场是CH,语言是CZE。旧的左联接方法会说它们都是OK的,因为它们都在每一列中,但是新的AND方法会把它们都显示为警告。我希望市场显示为OK,而语言显示为警告。

LookupMap_MarketLanguage Table
+----------------+-------+----------+-------+
|     Market     | MCode | Language | LCode |
+----------------+-------+----------+-------+
| Switzerland    | CH    | French   | FRE   |
| Switzerland    | CH    | German   | GER   |
| Czech Republic | CZ    | Czech    | CZE   |
| Germany        | DE    | German   | GER   |
+----------------+-------+----------+-------+
Sample CTable data
+--------------------+----------------------+
| campaignNameMarket | campaignNameLanguage |
+-------------------------------------------+
| DE                 | GER                  |
| CH                 | CZE                  |
| CZ                 | CZE                  |
+--------------------+----------------------+


Desired output
+----------+-------------+
| C_Market | C_Language  |
+----------+-------------+
| Ok       | Ok          |
| Ok       | Warning     |
| Ok       | Ok          |
+----------+-------------+
Current output with multiple left joins
+----------+-------------+
| C_Market | C_Language  |
+----------+-------------+
| Ok       | Ok          |
| Ok       | Ok          |
| Ok       | Ok          |
+----------+-------------+
Current output with AND LEFT JOIN
+----------+-------------+
| C_Market | C_Language  |
+----------+-------------+
| Ok       | Ok          |
| Warning  | Warning     |
| Ok       | Ok          |
+----------+-------------+
sql sql-server join left-join
1个回答
0
投票

可能你可以用existence查询代替join来做,即。

SELECT

CASE WHEN exists (select * 
from [dbo].[Lookup_Market] m 
where c.[campaignNameMarket] = C_Market.MCode and 
LEN(m.MCode) > 0
) THEN 'Ok' ELSE 'Warning' End as C_Market,

CASE WHEN exists (select * 
from [dbo].[dbo].[Lookup_Language] l 
where c.[campaignNameLanguage] =m.LCode and 
LEN(m.LCode) > 0
) THEN 'Ok' ELSE 'Warning' End as C_Language
FROM [dbo].[CTable] c;

EDIT:就像我之前说的,你的示例并没有涵盖所有的情况,也没有什么帮助。不过,至少现在比以前好一点了。如果这正是你想要的。

SELECT 
--     c.campaignNameMarket,
--     c.campaignNameLanguage,
       CASE
           WHEN EXISTS
                (
                    SELECT *
                    FROM dbo.LookupMap_MarketLanguage ml
                    WHERE c.campaignNameMarket = ml.MCode
                ) THEN 'Ok' ELSE 'Warning'
       END AS C_Market,
       CASE
           WHEN EXISTS
                (
                    SELECT *
                    FROM dbo.LookupMap_MarketLanguage ml
                    WHERE c.campaignNameMarket = ml.MCode
                          AND c.campaignNameLanguage = ml.LCode
                ) THEN 'Ok' ELSE 'Warning'
       END AS C_Language
FROM [dbo].[CTable] c;

你可以看看 DBFiddle演示在这里。

© www.soinside.com 2019 - 2024. All rights reserved.