多个 SQL SELECT WHERE 与 INTERSECT,占位值
Multiple SQL SELECT WHERE with INTERSECT, placeholder value
我正在使用 SQL 服务器并尝试执行以下操作:
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个都是null。但是 INTERSECT 不(正确)工作。
有没有不会干扰 INTERSECTS 的虚拟值。
我讨厌必须做嵌套的 ifs,如果我只有一个值,我只执行一个 SELECT。如果我有两个值,那么我有两个 SELECTS,中间有一个 INTERSECT 等等。
这是全部内容:
假设我有一个 5 个字符的单词,我希望能够做一个 SELECT WHERE 到 return 一个列表,其中包含 'i' 中的所有 5 个字符的单词第三名。很容易。那么我可能想要SELECT,其中第三个位置是'i',第五个是'e'。这类似于 "Wheel of Fortune"。我可能有所有五个值 a-b-i-d-e,所以只应遵守 returned 集。因此,最好有一组 5 SELECTS 和四个中间的 INTERSECTS,这样该构造可以处理 1 到 5 个值。
我试过 NULL 值,但显然行不通。
您还可以将查询构造为:
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;
与所有行相交是一个相交空操作。
戈登,这很有魅力!
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...
约翰尼
我正在使用 SQL 服务器并尝试执行以下操作:
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个都是null。但是 INTERSECT 不(正确)工作。
有没有不会干扰 INTERSECTS 的虚拟值。
我讨厌必须做嵌套的 ifs,如果我只有一个值,我只执行一个 SELECT。如果我有两个值,那么我有两个 SELECTS,中间有一个 INTERSECT 等等。
这是全部内容:
假设我有一个 5 个字符的单词,我希望能够做一个 SELECT WHERE 到 return 一个列表,其中包含 'i' 中的所有 5 个字符的单词第三名。很容易。那么我可能想要SELECT,其中第三个位置是'i',第五个是'e'。这类似于 "Wheel of Fortune"。我可能有所有五个值 a-b-i-d-e,所以只应遵守 returned 集。因此,最好有一组 5 SELECTS 和四个中间的 INTERSECTS,这样该构造可以处理 1 到 5 个值。
我试过 NULL 值,但显然行不通。
您还可以将查询构造为:
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;
与所有行相交是一个相交空操作。
戈登,这很有魅力!
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...
约翰尼