SELECT
ColAlphaNum,
ColId
FROM SomeTable
WHERE ColAlphaNum IN ('01AAA','02BBB','03CCC','04DDD')
该表包含值01AAA,02BBB的记录。 sql返回以下结果集(我只需要查询“ SomeTable”表中的数据
ColAlphaNum | ColId
------------+------
01AAA | 5
02BBB | 3
我想将不匹配的记录值返回为NULL,如下所示,但无法使其正常工作。
预期输出:
ColAlphaNum | total
------------+------
01AAA | 5
02BBB | 3
03CCC | NULL
04DDD | NULL
我试图通过case语句实现相同的目的,但是无法使其正常工作。尝试了此建议的解决方案Here可行,但是由于我必须从json列表中创建逗号分隔的ColAlphaNum值列表,并在上面的select语句中使用它们,所以union all选项可能很麻烦。有没有其他方法可以实现这一目标。
感谢您的帮助。
答案 0 :(得分:2)
使用类似LEFT JOIN
的方法从列表中构建表(在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
答案 1 :(得分:1)
如果IN (...)
子句中有大量项目,则可能更好,更有效的方法是创建一个临时表来保存匹配项。
此示例代码无法在SQL Server 2000上运行,因为它依赖于使用SQL Server 2000中不提供的功能创建的示例数据。话虽如此,您无需在实际系统上创建示例数据,因此这应该不是问题。另外,为什么要使用SQL SERVER 2000?那是将近20年的代码,并且完全不受Microsoft支持。一个人不禁想到安全隐患。
创建临时表:
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行的内容:
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.
显示临时表中的所有行,以及临时表中与SomeTable
中不匹配的行中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 ║ ╚══════════╩══════════════════════╝
答案 2 :(得分:0)
您可以使用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;