我正在使用SQL Server,并尝试执行以下操作:
SELECT dword FROM Details WHERE dskey = '51a'
INTERSECT
SELECT dword FROM Details WHERE dskey = '52b'
INTERSECT
SELECT dword FROM Details WHERE dskey = '53i'
INTERSECT
SELECT dword FROM Details WHERE dskey = '54d'
INTERSECT
SELECT dword FROM Details WHERE dskey = '55e';
这很好用。但是,我需要构建一个通用的SELECT,如:
SELECT dword FROM Details WHERE dskey = value1
INTERSECT
SELECT dword FROM Details WHERE dskey = value2
INTERSECT
SELECT dword FROM Details WHERE dskey = value3
INTERSECT
SELECT dword FROM Details WHERE dskey = value4
INTERSECT
SELECT dword FROM Details WHERE dskey = value5;
然而,在任何给定的执行中,我可能都没有获得所有五个关键值。我需要一些虚拟键值,不会干扰他的INTERSECT。
例如,假设我只有1个值,其余4个为空。但是INTERSECT没有(正确地)起作用。
无论如何都有虚拟值不会干扰INTERSECTS。
我讨厌必须做嵌套ifs,如果我只有一个值,我只执行一个SELECT。如果我有两个值,那么我有两个SELECTS,介入INTERSECT等等。
以下是这一切:
假设我有一个5个字符的单词,我希望能够在SELECT WHERE中返回一个说明所有5个字符单词的列表,其中包含' i'在第三位。很容易。然后我可能想要选择第三个位置是' i'第五个是' e。这类似于"财富之轮"。我可能有五个值a-b-i-d-e所以返回的集合应该只有。因此,如果有一组5个SELECTS和4个介入INTERSECTS,这个构造可以处理1到5个值,那将是很好的。
我尝试过NULL值,但显然不能正常工作。
答案 0 :(得分:3)
您还可以将查询构造为:
SELECT dword
FROM Details
WHERE dskey IN (value1, value2, value3, value4, value5)
GROUP BY dword
HAVING COUNT(DISTINCT dskey) = 5;
您仍然需要替换IN
列表和数字5.您可以使用显式参数来编写它:
WITH vals as (
SELECT v.val
FROM (VALUES (@value1), (@value2), (@value3), (@value4), (@value5)) v(val)
)
SELECT dword
FROM Details d JOIN
vals
ON d.dskey = vals.val
GROUP BY dword
HAVING COUNT(DISTINCT dskey) = (SELECT COUNT(*) FROM vals);
这是完全可参数化的并处理NULL
值。
编辑:
实际上,您也可以使用您的版本执行此操作:
SELECT dword FROM Details WHERE dskey = @value1 or @value1 IS NULL
INTERSECT
SELECT dword FROM Details WHERE dskey = @value2 or @value2 IS NULL
INTERSECT
SELECT dword FROM Details WHERE dskey = @value3 or @value3 IS NULL
INTERSECT
SELECT dword FROM Details WHERE dskey = @value4 or @value4 IS NULL
INTERSECT
SELECT dword FROM Details WHERE dskey = @value5 or @value5 IS NULL;
将所有行相交是交叉无操作。
答案 1 :(得分:0)
戈登这就像一个魅力!
use wofwords;
go
DECLARE @value1 varchar(25) = '51a';
DECLARE @value2 varchar(25) = '52b';
DECLARE @value3 varchar(25) = NULL;
DECLARE @value4 varchar(25) = NULL;
DECLARE @value5 varchar(25) = NULL;
SELECT dword FROM Details WHERE dskey = @value1 or @value1 IS NULL
INTERSECT
SELECT dword FROM Details WHERE dskey = @value2 or @value2 IS NULL
INTERSECT
SELECT dword FROM Details WHERE dskey = @value3 or @value3 IS NULL
INTERSECT
SELECT dword FROM Details WHERE dskey = @value4 or @value4 IS NULL
INTERSECT
SELECT dword FROM Details WHERE dskey = @value5 or @value5 IS NULL;
go
它给了我正确的答案,最重要的是,我现在可以编写c#部分并且只有一个查询而不是嵌套的ifs ...
约翰尼