我有三个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
我需要将Second / Third条件设为可选。我已经尝试了很多像case, (SELECT .. OR @B = null)
这样的东西,但由于它们是表值参数,因此无效。
答案 0 :(得分:1)
尝试使用OR
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
)
答案 1 :(得分:1)
如果只有第二和第三个条件是可选的,那么试试这个
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
)
答案 2 :(得分:1)
我已经看到并设置了存储过程,其中参数默认为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
答案 3 :(得分:1)
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匹配,那么你可以用它们做点什么吗?
答案 4 :(得分:1)
尝试以下方法。它以与原始查询相同的查询开始,但对于两个"可选的" 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)
)
查询(INSERT INTO @TestB
已注释掉)返回55
的值,因为@TestB是"可选"。但如果您取消注释INSERT INTO @TestB
,则不会返回任何内容,因为@TestB不包含值55
。
答案 5 :(得分:1)
这样做会更加清晰,同样简洁:
;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;
多个嵌套子查询和IN
操作的可读性较差,并且与使用CTE /表连接的效率可能较低。
如果考虑到性能,则可以使用索引临时表替换此模型中的CTE(Common Table Expression),如果您知道UNION
,UNION ALL
可以替换为n
1}}值在@A
,@B
和@C
之间是不同的。