条件行选择

时间:2016-10-24 08:32:19

标签: 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,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)   

1 个答案:

答案 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。