如何使用 sql 中的 IN 子句为不匹配的元素取回 NULL

How to get back NULLs for elements that did not match using IN clause in sql

SELECT 
  ColAlphaNum, 
  ColId 
FROM SomeTable 
WHERE ColAlphaNum IN ('01AAA','02BBB','03CCC','04DDD')

table 包含值 01AAA、02BBB 的记录。 sqlreturn是下面的结果集(我只需要查询"SomeTable"table的数据

 ColAlphaNum | ColId
 ------------+------
 01AAA       | 5
 02BBB       | 3

我想 return 将不匹配的记录值设置为 NULL,如下所示,但无法正常工作。

预期输出:

ColAlphaNum | total
------------+------
01AAA       | 5
02BBB       | 3
03CCC       | NULL
04DDD       | NULL

我试图用 case 语句实现同样的效果,但无法让它工作。尝试了这个建议的解决方案 Here 它有效但是因为我必须从 json 列表创建一个逗号分隔的 ColAlphaNum 值列表并在上面的 select 语句中使用它们,union all 选项可能很麻烦。有没有办法通过其他方式实现这一点。

感谢您的帮助。

您可以使用 values 构建并执行 left join :

select t.ColAlphaNum, s.ColId as total
from ( values ('01AAA'),('02BBB'),('03CCC'),('04DDD') 
     ) t(ColAlphaNum) left join
     SomeTable s
     on s.ColAlphaNum = t.ColAlphaNum; 

使用 UNION ALLLEFT JOIN 从列表中构建一个 table(应该在 SQL 2000 中工作):

SELECT List.ListItem, SomeTable.ColId
FROM (
    SELECT '01AAA' UNION
    SELECT '02BBB' UNION
    SELECT '03CCC' UNION
    SELECT '04DDD'
) AS List(ListItem)
LEFT JOIN SomeTable ON List.ListItem = SomeTable.ColAlphaNum

如果 IN (...) 子句中有大量项目,一个可能更好、更有效的方法可能是创建一个临时 table 来保存匹配项。

此示例代码不会 运行 在 SQL Server 2000 上,因为它依赖于使用 SQL Server 2000 中不可用的功能创建的示例数据。话虽如此,您不需要在真实系统上创建样本数据,所以这应该不是问题。另外,为什么 SQL SERVER 2000????那是将近 20 年的代码,并且完全不受 Microsoft 的支持。一想到安全隐患就不寒而栗。

创建临时文件 table:

IF OBJECT_ID(N'tempdb...#Matches', N'U') IS NOT NULL
DROP TABLE #Matches;
CREATE TABLE #Matches
(
    AlphaNum char(5) NOT NULL
        CONSTRAINT Matches_pk
        PRIMARY KEY
        CLUSTERED
);

向其中插入 100 行测试数据(这不会 运行 在 SQL Server 2000 上):

INSERT INTO #Matches (AlphaNum)
SELECT TOP(100) 
    RIGHT('00' + CONVERT(varchar(2)
        , ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) - 1  ), 2)
    + CHAR((CRYPT_GEN_RANDOM(1) & 25) + 65)
    + CHAR((CRYPT_GEN_RANDOM(1) & 25) + 65)
    + CHAR((CRYPT_GEN_RANDOM(1) & 25) + 65)
FROM sys.syscolumns c1;

临时文件中 10 行的内容 table:

SELECT TOP(10) *
FROM #Matches;
╔══════════╗
║ AlphaNum ║
╠══════════╣
║ 00BQY    ║
║ 01RZJ    ║
║ 02YQB    ║
║ 03JAY    ║
║ 04QJB    ║
║ 05QIB    ║
║ 06ZYY    ║
║ 07QBJ    ║
║ 08ZAI    ║
║ 09QBA    ║
╚══════════╝

根据您的问题创建 SomeTable,并用 10,000 行填充它:

IF OBJECT_ID('dbo.SomeTable', N'U') IS NOT NULL
DROP TABLE dbo.SomeTable;
CREATE TABLE dbo.SomeTable
(
    SomeTableID int NOT NULL IDENTITY(1,1)
        CONSTRAINT SomeTable_pk
        PRIMARY KEY
        CLUSTERED
    , AlphaNum char(5) NOT NULL
    , SomeCol varchar(500) NOT NULL
);

插入一些测试数据(同样,这部分不会 运行 在 SQL Server 2000 上):

INSERT INTO dbo.SomeTable (AlphaNum, SomeCol)
SELECT TOP(10000) 
    AlphaNum = RIGHT('00' + CONVERT(varchar(2)
               , (ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) - 1) % 99)
               , 2)
        + CHAR((CRYPT_GEN_RANDOM(1) & 25) + 65)
        + CHAR((CRYPT_GEN_RANDOM(1) & 25) + 65)
        + CHAR((CRYPT_GEN_RANDOM(1) & 25) + 65)
    , SomeCol = CONVERT(varchar(1000), CRYPT_GEN_RANDOM(500))
FROM sys.syscolumns c1
    CROSS JOIN sys.syscolumns c2;

创建支持的非聚集索引:

CREATE NONCLUSTERED INDEX SomeTable_AlphaNum
ON dbo.SomeTable (AlphaNum)
INCLUDE (SomeCol); --INCLUDE clause does not work on SQL Server 2000, ignore it.

显示临时 table 中的所有行,其中 SomeTable 的匹配项和临时 table 中没有匹配项的行的 NULL 值在 SomeTable 中(这绝对适用于 SQL Server 2000!):

SELECT m.AlphaNum
    , st.SomeCol
FROM #Matches m
    LEFT JOIN dbo.SomeTable st ON m.AlphaNum = st.AlphaNum;

该输出的前 20 行:

╔══════════╦══════════════════════╗
║ AlphaNum ║       SomeCol        ║
╠══════════╬══════════════════════╣
║ 00BQY    ║ NULL                 ║
║ 01RZJ    ║ NULL                 ║
║ 02YQB    ║ NULL                 ║
║ 03JAY    ║ NULL                 ║
║ 04QJB    ║ NULL                 ║
║ 05QIB    ║ NULL                 ║
║ 06ZYY    ║ NULL                 ║
║ 07QBJ    ║ SR{m‘x ™¨Hó‹µäôÅPÓ   ║
║ 08ZAI    ║ NULL                 ║
║ 09QBA    ║ NULL                 ║
║ 10RQA    ║ NULL                 ║
║ 11IAZ    ║ NULL                 ║
║ 12RZI    ║ NULL                 ║
║ 13ZRA    ║ NULL                 ║
║ 14IAI    ║ NULL                 ║
║ 15BIZ    ║ NULL                 ║
║ 16JBI    ║ NULL                 ║
║ 17AYJ    ║ Å N©U…C4Mòº³5ö„iÅ    ║
║ 18ZJI    ║ NULL                 ║
║ 19YRI    ║ NULL                 ║
╚══════════╩══════════════════════╝