我正在尝试从表中选择最适用的(最通用的)行
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
OR
DECLARE @Bid INT=1, @Did INT=1,@Pid INT=1,@Vid INT=6
列值NULL表示它可以适用于任何参数值。
例如,如果所有值都为null,则表示它是一种主行。但如果掌握" SomeData"需要有所不同,让我们说为Vid 1,然后我们创建行将所有值null,但Vid值为1.
列的优先级是从左到右。
此外,如果值为
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)
答案 0 :(得分:3)
如果您不需要担心重复项,即多个具有相同匹配数的行,则可以尝试以下查询:
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与输入变量匹配的顺序排序的所有ID。