我正试图找出我的查询出了什么问题,因为它没有排除我想在not in子句中排除的行。我真的很感激你的建议。提前感谢
我有两张桌子
TableOne
Id Name isHealthy
1 Apple Y
2 Banana Y
3 Grapes Y
4 Guava Y
5 Orange Y
TableX
Id VALUE isActive DESCRIPTION
1 Apple,Banana 1 FRUITS
2 Orange 0 FRUITS
3 Grapes,Guava 1 FRUITS
我想在TableOne行中排除TableX值的所有列名
DECLARE @EXCLUDEVAL VARCHAR(max) = (SELECT ''''
+ Replace( String_agg([value], ','), ',', ''',''')
+ '''' AS EXCLUDEVAL
FROM tablex
WHERE [description] = 'FRUITS'
AND isactive = '1');
SELECT *
FROM tableone
WHERE NAME NOT IN ( @EXCLUDEVAL );
我进行了这个查询,但它不排除@EXCLUDEVAL
将返回这个值
'Apple','Banana','Grapes','Guava'
如果我在查询中不使用变量@EXCLUDEVAL
而输入确切的值,它会起作用并排除,但我不想要硬编码。我想在where子句中使用变量@EXCLUDEVAL
,但我不能确定哪里出了问题。
您混合了静态和动态SQL,这是行不通的。
您还遵循了糟糕的数据库设计,将多个值存储在一行中,并使用逗号分隔它们。关系数据库的目的是每行/每列存储一个值。如果你能够改变这一点,这将使你未来的生活更加轻松。
假设你可以完整的静态版本是:
SELECT *
FROM tableone
WHERE [NAME] NOT IN (
SELECT [value]
FROM tablex
WHERE [description] = 'FRUITS'
AND isactive = '1'
);
但是,如果您无法更改设计,并且正在使用数据库兼容性130或更高版本,则可以将STRING_SPLIT
与CROSS APPLY
结合使用来实现您想要的功能。
SELECT *
FROM tableone
WHERE [NAME] NOT IN (
SELECT R.Result
FROM tablex X
CROSS APPLY (
SELECT [value] Result
FROM STRING_SPLIT(X.[VALUE],',')
) R
WHERE [description] = 'FRUITS'
AND isactive = '1'
);
或者,如果你使用的是旧的兼容性,你需要实现你自己的字符串分割功能,其中有很多可以通过快速谷歌获得,然后再次使用CROSS APPLY
:
SELECT *
FROM tableone
WHERE [NAME] NOT IN (
SELECT R.Result
FROM tablex X
CROSS APPLY dbo.MyStringSplitFunction(X.[Value],',') R
WHERE [description] = 'FRUITS'
AND isactive = '1'
);