查找匹配的记录集

时间:2014-11-03 19:25:25

标签: sql sql-server sql-server-2008-r2

我在SQL Server 2008R2上有以下表格

消息表

  ContrlNo|    LineNo     |    Msg
    1     |        1      |    Tiger1 Text
    1     |        2      |    Tiger1 Text
    1     |        3      |    Tiger1 Text
    1     |        4      |    Tiger1 Text
    2     |        1      |    Tiger1 Text1
    2     |        2      |    Tiger1 Text2
    2     |        3      |    Tiger1 Text3
    2     |        4      |    Tiger1 Text4
    3     |        1      |    Horse 1
    3     |        2      |    Horse 2
    3     |        3      |    Horse 3
    3     |        4      |    Horse 4

RuleTable

RuleNo|    MsgLineNo  | RuleStartingPos |    RuleMsg
1     |        1      |  1              |  Tiger1 Text
2     |        1      |  1              |  Tiger1 Text
2     |        3      |  1              |  Tiger1 Text3

对于MESSAGETABLE中的每组ControlNo记录,我想应用RULETABLE中的规则并列出RULENo(如果有的话)。

如果您看到RuleTable,则规则2与规则1重叠。并且要求是为每个控制号获取最匹配的RuleNo。预期的结果是,

ContrlNo | RuleNo
1   |   1 
2   |   2 
3   |   NULL

谢谢, 杰

2 个答案:

答案 0 :(得分:0)

第一个子查询获得总匹配规则,第二个子查询获得总规则,当这两个条件匹配时,我们显示RuleNo其他明智的NULL,因为我们使用LEFT JOIN

Select A.ContrlNo, ISNULL(T.RuleNo,0) as RuleNo FROM
(  select ContrlNo, COUNT(R.RuleNo) as MatchedRules
   FROM Messages M
   LEFT JOIN Rules R
   on M.[LineNo] = R.MsgLineNo
   and SUBSTRING(M.Msg,R.RuleStartingPos,LEN(R.RuleMsg)) = R.RuleMsg
   AND M.ContrlNo = R.RuleNo
GROUP BY M.ContrlNo) A
LEFT JOIN (  
    select COUNT(MsgLineNo) as TotalRules, RuleNo 
    from Rules R1  
    group by RuleNo) T
    ON A.MatchedRules = T.TotalRules

答案 1 :(得分:0)

我相信以下内容将检索列出的结果:它将显示一个控件号,其中包含具有最匹配行的关联规则(如果在第一种情况下,两个规则具有相同数量的匹配,则会检查MatchPercent)。

SELECT MT.ContrlNo, r.RuleNo, r.MatchPercent
FROM
  MessageTable MT
   LEFT JOIN 
    (
      SELECT 
        ContrlNo,
        RuleNo, 
        MatchedRules / AvailableRules AS MatchPercent,
        ROW_NUMBER() OVER (PARTITION BY ContrlNo ORDER BY MatchedRules DESC, MatchedRules / AvailableRules DESC) AS rn
      FROM 
        (
          SELECT 
            ContrlNo, 
            R.RuleNo, 
            COUNT(*) as MatchedRules,
            (SELECT COUNT(*) FROM RuleTable WHERE RuleTable.RuleNo = R.RuleNo) + 0.0 AS AvailableRules
          FROM 
              MessageTable M
               INNER JOIN 
              RuleTable R ON 
                  M.[LineNo] = R.MsgLineNo AND 
                  SUBSTRING(M.Msg,R.RuleStartingPos,LEN(R.RuleMsg)) LIKE '%' + R.RuleMsg + '%'
          GROUP BY M.ContrlNo, R.RuleNo
        ) q
     ) r ON 
    MT.ContrlNo = r.ContrlNo AND
    r.rn = 1
GROUP BY MT.ContrlNo, r.RuleNo, r.MatchPercent

SQL Fiddle