Sql server 条件行选择
我试图从表中选择最适用(最通用)的行Sql server 条件行选择,sql-server,tsql,sql-server-2014,Sql Server,Tsql,Sql Server 2014,我试图从表中选择最适用(最通用)的行 CREATE TABLE #T(Id int, Bid int, Did int,Pid int, Vid int, SomeData varchar(10)) INSERT INTO #T VALUES(1,1,1,1,1,'Data1'), (2,1,1,NULL,5,'Data2'), (3,1,1,NULL,6,'Data3'), (4,1,1,8,NULL,'Data4'), (5,1,NULL,N
CREATE TABLE #T(Id int, Bid int, Did int,Pid int, Vid int, SomeData varchar(10))
INSERT INTO #T
VALUES(1,1,1,1,1,'Data1'),
(2,1,1,NULL,5,'Data2'),
(3,1,1,NULL,6,'Data3'),
(4,1,1,8,NULL,'Data4'),
(5,1,NULL,NULL,NULL,'Data5')
SELECT *
FROM #T
当我使用下面的参数值时,我期望的行Id为1,因为它包含从参数传递的所有值
DECLARE @Bid INT=1,
@Did INT=1,
@Pid INT=1,
@Vid INT=1
当我使用以下值时,我期望的行Id为5。因为没有与Pid 1和Vid Null匹配的行。因此,这些参数最通用的行是Id=5的行
DECLARE @Bid INT=1,@Did INT =1,@Pid INT =1,@Vid INT =NULL
或
列值NULL表示它可以应用于任何参数值
e、 g如果all的值为null,则表示它是一种主行。但如果主“SomeData”需要不同,比如说对于vid1,那么我们创建的行将所有值都为null,但值为1的Vid除外
列的优先级从左到右
如果值为
DECLARE @Bid INT=1,@Did INT =1,@Pid INT =10,@Vid INT =1
预期的行是id为5的行
我尝试了下面的查询,但它返回多行。有没有办法做到这一点
SELECT *
FROM #T
WHERE ((Bid = @Bid) OR Bid IS NULL)
AND ((Did = @Did) OR Did IS NULL)
AND ((Pid = @Pid) OR Pid IS NULL)
AND ((Vid = @Vid) OR Vid IS NULL)
如果不需要担心重复,即多行具有相同的匹配数,则可以尝试以下查询:
SELECT TOP 1 t.Id
FROM
(
SELECT Id,
CASE WHEN Bid = @Bid OR (Bid IS NULL AND @Bid IS NOT NULL)
THEN 1 ELSE 0 END AS BidMatch
CASE WHEN Did = @Did OR (Did IS NULL AND @Did IS NOT NULL)
THEN 1 ELSE 0 END AS DidMatch
CASE WHEN Pid = @Pid OR (Pid IS NULL AND @Pid IS NOT NULL)
THEN 1 ELSE 0 END AS PidMatch
CASE WHEN Vid = @Vid OR (Vid IS NULL AND @Vid IS NOT NULL)
THEN 1 ELSE 0 END AS VidMatch
FROM #T
) t
ORDER BY t.BidMatch DESC,
t.DidMatch DESC,
t.PidMatch DESC,
t.VidMatch DESC
您只需删除查询开始处的
TOP 1
子句,就可以看到所有ID按照它们与输入变量的匹配程度降序排列。这样更好。唯一的问题是复制品。如果我有从左到右的列优先级,我们可以用它来消除重复吗?你说的从左到右是什么意思?你能举个清楚的例子说明你的意思吗?请记住,这种方式排序可能会变得混乱,因为即使只有4列,也有太多的排列。例如,我们正在计算匹配计数。如果我们有两行1,8,1,NULL和1,NULL,1,5,并且我们传递参数值1,8,NULL,5,那么这两行都有匹配计数2。但我希望得到第一排作为结果。因为它按顺序匹配1,8,然后在第二行中匹配5作为vid。这有帮助吗?这没有帮助,因为你没有给出排名系统。例如,1,NULL,NULL,NULL
和NULL,8,NULL,5
,输入1,8,NULL,5
。。。第一条记录与第一条匹配,但仅与第一条匹配。但随后的两个较小的匹配是否比第一个匹配更重要?希望你能看到这是怎么回事……如果我通过1,1,10,1
,它将得到id为1的匹配项。但这将是不正确的,因为该行是PID-1的专用行,这里我们寻找PID-10。因此,这种情况下的最佳匹配是最后一行(Id为5)
SELECT TOP 1 t.Id
FROM
(
SELECT Id,
CASE WHEN Bid = @Bid OR (Bid IS NULL AND @Bid IS NOT NULL)
THEN 1 ELSE 0 END AS BidMatch
CASE WHEN Did = @Did OR (Did IS NULL AND @Did IS NOT NULL)
THEN 1 ELSE 0 END AS DidMatch
CASE WHEN Pid = @Pid OR (Pid IS NULL AND @Pid IS NOT NULL)
THEN 1 ELSE 0 END AS PidMatch
CASE WHEN Vid = @Vid OR (Vid IS NULL AND @Vid IS NOT NULL)
THEN 1 ELSE 0 END AS VidMatch
FROM #T
) t
ORDER BY t.BidMatch DESC,
t.DidMatch DESC,
t.PidMatch DESC,
t.VidMatch DESC