首页 > 解决方案 > 内连接为真条件下的左连接 SQL-MS-ACCESS

问题描述

在加入两个子查询(sub1 和 sub2)时,我有两种情况。Case1:sub2.fldvalue 和 sub2.fldvalue _Override 中至少有一个非空值。在这种情况下,我想保留 sub1.Bloomb_Allocation 的所有值,所以我需要 LEFT JOIN。Case2:sub2.fldValue 和 sub2.fldValue_Override 中的所有值都为空。在这种情况下,我不想保留 sub1.Bloomb_Allocation 的值,所以我需要一个 INNER JOIN。:

查询结果CASE 1(isin='LU1956838830'):

SELECT  sub1.BB_allocation AS cln1 , sub2.fldValue AS cln2, sub2.fldValue_Override AS cln3
FROM( 
(SELECT Bloomb_Allocation, BB_allocation, ordine FROM dbBloomFields WHERE Bloomb_Blk='Asset Type') AS sub1 
Left Join 
(SELECT blkName, fldValue, fldValue_Override FROM  dbSecurityMacroAllocation  WHERE isin= 'LU1956838830') AS sub2 
ON sub1.BB_Allocation=sub2.blkName)
GROUP BY  sub1.BB_allocation  , sub2.fldValue , sub2.fldValue_Override, sub1.ordine
ORDER BY sub1.ordine
cln1 cln2 cln3
现金及其他 无效的 无效的
纽带 无效的 无效的
公平 100 无效的
选择 无效的 无效的
不详 无效的 无效的

与:子1:

Bloomb_Allocation BB_allocation 秩序
选择 选择 4
纽带 纽带 2
现金及其他 现金及其他 1
公平 公平 3
货币市场 现金及其他 1
不详 不详 5

子2

块名 fldValue_Override
公平 100 无效的

查询结果 CASE 2(保持 LEFT JOIN with isin= 'abcd123456',不存在于表 dbSecurityMacroAllocation 中):

SELECT  sub1.BB_allocation AS cln1 , sub2.fldValue AS cln2, sub2.fldValue_Override AS cln3
FROM( 
(SELECT Bloomb_Allocation, BB_allocation, ordine FROM dbBloomFields WHERE Bloomb_Blk='Asset Type') AS sub1 
Left Join 
(SELECT blkName, fldValue, fldValue_Override FROM  dbSecurityMacroAllocation  WHERE isin= 'abcd123456') AS sub2 
ON sub1.BB_Allocation=sub2.blkName)
GROUP BY  sub1.BB_allocation  , sub2.fldValue , sub2.fldValue_Override, sub1.ordine
ORDER BY sub1.ordine
cln1 cln2 cln3
现金及其他 无效的 无效的
纽带 无效的 无效的
公平 无效的 无效的
选择 无效的 无效的
不详 无效的 无效的

与:子1:

Bloomb_Allocation BB_allocation 秩序
选择 选择 4
纽带 纽带 2
现金及其他 现金及其他 1
公平 公平 3
货币市场 现金及其他 1
不详 不详 5

子2

块名 fldValue_Override
无效的 无效的 无效的

如何编写查询以获取案例 2 的结果,例如:

cln1 cln2 cln3
无效的 无效的 无效的

标签: sqlms-access

解决方案


我认为您想要进行 INNER JOIN(仅返回两个子查询中匹配的行),而不是 LEFT JOIN(返回左子查询中的所有记录和右子查询中的匹配记录)。让我知道我是否正确。

SELECT sub1.BB_allocation AS cln1, 
       sub2.fldValue AS cln2, 
       sub2.fldValue_Override AS cln3

FROM (SELECT Bloomb_Allocation, BB_allocation, ordine FROM dbBloomFields WHERE Bloomb_Blk='Asset Type') AS sub1 

INNER JOIN (SELECT blkName, fldValue, fldValue_Override FROM  dbSecurityMacroAllocation  WHERE isin= 'LU1956838830') AS sub2 ON sub1.BB_Allocation = sub2.blkName

GROUP BY  sub1.BB_allocation, sub2.fldValue, sub2.fldValue_Override, sub1.ordine
ORDER BY sub1.ordine;

您的查询结果是错误的,因为如果您通过 LEFT JOIN sub1 和 sub2 查询sub1.BB_Allocation = sub2.blkName,第二行的结果 cln2 值应该为 NULL,而不是“bond”。

你也可以这样查询:

SELECT  sub1.BB_allocation AS cln1, 
        sub2.fldValue AS cln2, 
        sub2.fldValue_Override AS cln3
        
FROM dbBloomFields AS sub1
INNER JOIN dbSecurityMacroAllocation AS sub2 ON sub1.BB_Allocation = sub2.blkName
WHERE sub1.Bloomb_Blk = 'Asset Type' AND sub2.isin = 'LU1956838830'
GROUP BY  sub1.BB_allocation, sub2.fldValue, sub2.fldValue_Override, sub1.ordine
ORDER BY sub1.ordine;

您可以尝试这样的方法来解决 CASE 1 和 CASE 2:

首先,如果 sub2 有任何行,我会在 sub1 和 sub2 查询之间进行 UNION,然后进行左连接以获取剩余的 sub2 值,最后进行 INNER JOIN。

如果 sub2 返回 none 行,则结果将为空。如果 sub2 返回至少一行,那么结果将是 sub1 和 sub2 之间的左连接。

也许有更好的解决方案,但这是我的第一个解决方案。

SELECT  sub1.BB_allocation AS cln1, 
        sub2.fldValue AS cln2, 
        sub2.fldValue_Override AS cln3
        
FROM dbBloomFields AS sub1
INNER JOIN (

    SELECT u1.blkName, lj1.fldValue, lj1.fldValue_Override
    FROM (

        SELECT CASE WHEN (SELECT COUNT(blkName) > 0 FROM  dbSecurityMacroAllocation WHERE isin = 'LU1956838830') THEN BB_allocation ELSE NULL END AS blkName
        FROM dbBloomFields WHERE Bloomb_Blk='Asset Type'

        UNION

        SELECT blkName FROM dbSecurityMacroAllocation WHERE isin = 'LU1956838830' ) AS u1

    LEFT JOIN dbSecurityMacroAllocation AS lj1 ON u1.blkName = lj1.blkName) sub2 ON sub1.BB_Allocation = sub2.blkName

WHERE sub1.Bloomb_Blk = 'Asset Type'
GROUP BY  sub1.BB_allocation, sub2.fldValue, sub2.fldValue_Override, sub1.ordine
ORDER BY sub1.ordine;

推荐阅读