Sql server SQL Server-可选where子句-空表值参数
我有三个TVP-A,B和C A永远不会是空的。B或C可以为空Sql server SQL Server-可选where子句-空表值参数,sql-server,sql-server-2008,tsql,Sql Server,Sql Server 2008,Tsql,我有三个TVP-A,B和C A永远不会是空的。B或C可以为空 AND SomeId IN (SELECT n FROM @A) -- First AND SomeId IN (SELECT n FROM @B) -- Second -- Make this optional AND SomeId IN (SELECT n FROM @C) -- Third -- Make this optional 我需要将第二个/第三个条件设置为可选。我已经尝试了很多方法,比如case,(SELECT..或
AND
SomeId IN (SELECT n FROM @A) -- First
AND
SomeId IN (SELECT n FROM @B) -- Second -- Make this optional
AND
SomeId IN (SELECT n FROM @C) -- Third -- Make this optional
我需要将第二个/第三个条件设置为可选。我已经尝试了很多方法,比如
case,(SELECT..或@B=null)
,但是由于这些都是表值参数,所以它不起作用 尝试使用或
AND
(
SomeId IN (SELECT n FROM @A) -- First
OR
SomeId IN (SELECT n FROM @B) -- Second -- Make this optional
OR
SomeId IN (SELECT n FROM @C) -- Third -- Make this optional
)
尝试使用或
AND
(
SomeId IN (SELECT n FROM @A) -- First
OR
SomeId IN (SELECT n FROM @B) -- Second -- Make this optional
OR
SomeId IN (SELECT n FROM @C) -- Third -- Make this optional
)
如果只有第二个和第三个条件是可选的,请尝试此操作
AND SomeId IN (SELECT n FROM @A) -- First
OR
(
SomeId IN (SELECT n FROM @B) -- Second -- Make this optional
OR
SomeId IN (SELECT n FROM @C) -- Third -- Make this optional
)
如果只有第二个和第三个条件是可选的,请尝试此操作
AND SomeId IN (SELECT n FROM @A) -- First
OR
(
SomeId IN (SELECT n FROM @B) -- Second -- Make this optional
OR
SomeId IN (SELECT n FROM @C) -- Third -- Make this optional
)
我看到并设置了参数默认为NULL的存储过程
@A int = NULL,
@B int = NULL,
@C int = NULL
隐藏的代码将加载到参数中,@B和@C可以加载,也可以不加载
当您到达WHERE
子句时,您将
SomeId IN (SELECT n FROM @A)
AND (SomeID IN (SELECT n FROM @B) OR @B IS NULL)
AND (SomeID IN (SELECT n FROM @C) OR @C IS NULL)
注意语法;它不是@B=NULL
,而是@B is NULL
我看到并设置了参数默认为NULL的存储过程
@A int = NULL,
@B int = NULL,
@C int = NULL
SELECT m.*, a.N, b.N, c.N FROM MyTable m
INNER JOIN @A a
ON a.N = m.SomeId
LEFT JOIN @B b
ON b.N = m.SomeId
LEFT JOIN @C c
ON c.N = m.SomeId
隐藏的代码将加载到参数中,@B和@C可以加载,也可以不加载
当您到达WHERE
子句时,您将
SomeId IN (SELECT n FROM @A)
AND (SomeID IN (SELECT n FROM @B) OR @B IS NULL)
AND (SomeID IN (SELECT n FROM @C) OR @C IS NULL)
注意语法;它不是@B=NULL
,它是@B是NULL
SELECT m.*, a.N, b.N, c.N FROM MyTable m
INNER JOIN @A a
ON a.N = m.SomeId
LEFT JOIN @B b
ON b.N = m.SomeId
LEFT JOIN @C c
ON c.N = m.SomeId
因此,您试图获取所有与a匹配的记录,如果它们与b或c匹配,那么您可以对它们做些什么
因此,您正在尝试获取与a匹配的所有记录,如果它们与b或c匹配,则可以对它们进行处理。尝试以下操作。它以与原始查询相同的查询开始,但对于两个“可选”TVP中的每一个,它都添加了一个UNION ALL以选择“SomeId”,仅当该特定TVP中现在有行时。如果TVP中有行,则保持将其用作过滤器的意图,否则它不会过滤掉该行
DECLARE @Main TABLE (ID INT);
INSERT INTO @Main (ID) VALUES (55);
INSERT INTO @Main (ID) VALUES (999);
DECLARE @TestA TABLE (Col1 INT);
INSERT INTO @TestA (Col1) VALUES (55);
INSERT INTO @TestA (Col1) VALUES (67855);
DECLARE @TestB TABLE (Col1 INT);
--INSERT INTO @TestB (Col1) VALUES (565);
SELECT tmp.ID
FROM @Main tmp
WHERE tmp.ID IN (SELECT Col1 FROM @TestA)
AND tmp.ID IN (
SELECT Col1 FROM @TestB
UNION ALL
SELECT tmp.ID
WHERE NOT EXISTS(SELECT * FROM @TestB)
)
查询(将插入@TestB
注释掉)返回55
的值,因为@TestB是“可选的”。但是如果您取消注释将插入@TestB
,则不会返回任何内容,因为@TestB不包含值55
,请尝试以下操作。它以与原始查询相同的查询开始,但对于两个“可选”TVP中的每一个,它都添加了一个UNION ALL以选择“SomeId”,仅当该特定TVP中现在有行时。如果TVP中有行,则保持将其用作过滤器的意图,否则它不会过滤掉该行
DECLARE @Main TABLE (ID INT);
INSERT INTO @Main (ID) VALUES (55);
INSERT INTO @Main (ID) VALUES (999);
DECLARE @TestA TABLE (Col1 INT);
INSERT INTO @TestA (Col1) VALUES (55);
INSERT INTO @TestA (Col1) VALUES (67855);
DECLARE @TestB TABLE (Col1 INT);
--INSERT INTO @TestB (Col1) VALUES (565);
SELECT tmp.ID
FROM @Main tmp
WHERE tmp.ID IN (SELECT Col1 FROM @TestA)
AND tmp.ID IN (
SELECT Col1 FROM @TestB
UNION ALL
SELECT tmp.ID
WHERE NOT EXISTS(SELECT * FROM @TestB)
)
查询(将插入@TestB
注释掉)返回55
的值,因为@TestB是“可选的”。但是如果您取消注释将插入@TestB
,则不会返回任何内容,因为@TestB不包含值55
,执行以下操作将更加简洁明了:
;WITH AllowedIds_CTE (SomeId) AS (
SELECT n from @A
UNION
SELECT n from @B
UNION
SELECT n from @C
)
SELECT * FROM SomeTable O
JOIN AllowedIds_CTE A
ON O.SomeId = A.SomeId;
多个嵌套子查询和
中的
操作的可读性和效率都不如与CTE/表的联接
如果性能是一个问题,UNION
可以替换为UNION ALL
,如果您知道您的n
值在@a
中是不同的,@B
和@C
执行以下操作将更加简洁明了:
;WITH AllowedIds_CTE (SomeId) AS (
SELECT n from @A
UNION
SELECT n from @B
UNION
SELECT n from @C
)
SELECT * FROM SomeTable O
JOIN AllowedIds_CTE A
ON O.SomeId = A.SomeId;
多个嵌套子查询和
中的
操作的可读性和效率都不如与CTE/表的联接
如果性能是一个问题,
UNION
可以替换为UNION ALL
,如果您知道您的n
值在@a
、@B
和@C
之间是不同的,则可以用索引临时表替换此模型中的CTE()。这不起作用。@AseemGautam:我认为DWF走上了正确的轨道。类似于SomeID IN(从@A中选择n)和(EXISTS(从@B中选择1)以及SomeID IN(从@B中选择n))
。。。这对您的目的不起作用吗?这些是表值参数。这不起作用。@AseemGautam:我认为DWF走上了正确的轨道。类似于SomeID IN(从@A中选择n)和(EXISTS(从@B中选择1)以及SomeID IN(从@B中选择n))
。。。这不符合你的目的吗?它们不是参数。。它们是表变量,不是参数。。它们是表变量。