Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/codeigniter/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql server 条件行选择_Sql Server_Tsql_Sql Server 2014 - Fatal编程技术网

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