【问题标题】:SQL Find most rows that match between two tablesSQL查找两个表之间匹配的大多数行
【发布时间】:2016-09-25 08:55:42
【问题描述】:

我正在使用 SQL Server 2012 我有两个如下表

表 1 和表 2 都有很多组,由组列表示。组的名称可能在两个表中都匹配,但可能不匹配。重要的是在表 2 上找到与表 1 上的组中的成员匹配的成员最多的组。

我首先尝试使用 vlookup 执行此操作,但问题是 vlookup 会拉取 Group 列中匹配的第一个条目,而不是匹配最多的组。下面的 vlookup 会拉 BBB,但正确的结果是 CCC。

可能会出现平局。 Table2 上可能有多个组与 Table1 匹配且具有相同数量的成员,因此最好的方法可能是计算匹配数,但是有数千个组,因此对具有计数的列进行排序和筛选并不理想.我需要类似 case 语句的内容,如果存在 MAX(match),那么 Table1 将在派生列 BestMatch 中显示具有 MAX(Match) 的组名。如果该列可以显示表 2 中具有 MAX(Match 可能是一个或多个的所有组。也许它可以用逗号分隔。

如果不是,如果列只能说 tie 并且我可以查找 tie,那么如果这是最佳选择,那将是理想的,当出现 tie 一词时,除了每个匹配的成员之外,它会重复,所以我会知道要查找对于匹配哪些帐户以及匹配的帐户数量的组。

【问题讨论】:

  • 最佳匹配是AAAA。我认为这是一个错字?
  • 示例表数据很棒。如果你也加上预期的结果就更好了!
  • 是 AAAA 是错字应该是 AAA

标签: sql sql-server count match


【解决方案1】:
select  *
from    Table1 t1
    outer apply
    (
        select top 1 t2.[Group]
        from   Table2 t2
        where   t2.Member   = t1.Member
        group by t2.[Group]
        order by count(*) desc
    ) m

【讨论】:

    【解决方案2】:

    这可能不是最优雅的解决方案,但我认为它可以完成工作:

    select *
    from
        (select t1.[group] as t1group, t1.member, t2.[group] as t2group
         from Table1 t1 inner join Table2 t2 on t1.member = t2.member)a
    where member = (select max(t1.member) 
                    from Table1 t1 inner join Table2 t2 on t1.member = t2.member)
    

    如果 Table2 中的 2 行与 Table1 中的最大成员匹配,则会显示两个结果

    PS:你想要的结果的例子会很有帮助

    【讨论】:

      【解决方案3】:

      我们确实可以使用一些预期的输出来帮助澄清问题。

      如果我对您的理解正确,此查询将使您接近所需的结果:

      ;with cte as
      (    SELECT t1a.[group] AS Group1
                , t2a.[Group] AS Group2
                , RANK() OVER(PARTITION BY t1a.[group] 
                                  ORDER BY COUNT(t2a.[Group]) DESC) AS MatchRank
             FROM Table1 t1a
             JOIN Table2 t2a
               ON t1a.member = t2a.member
         GROUP BY t1a.[group], t2a.[GRoup])
       SELECT * 
         FROM cte
        WHERE MatchRank=1
      

      查询不会识别平局,但会显示任何平局结果...

      如果您是公用表表达式(;with 语句)的新手,这里有一个有用的描述 here

      【讨论】:

        【解决方案4】:

        计算每个组对的成员匹配并对其进行排名,以便匹配计数最高的组对获得排名第一。找到这些后,您可以从 table1 和 table2 中选择相关记录。

        select t1.grp, t1.member, t2.grp
        from t1
        join
        (
          select 
            t1.grp as grp1, 
            t2.grp as grp2, 
            rank() over (order by count(*) desc) as rnk
          from t1
          join t2 on t2.member = t1.member
          group by t1.grp, t2.grp
        ) grps on grps.rnk = 1 and grps.grp1 = t1.grp
        left join t2 on t2.grp = grps.grp2 and t2.member = t1.member
        order by t1.grp, t1.member, t2.grp;
        

        这使您可以将领带分成不同的行,例如对于 AAA 有四个不同的成员 (123,456,789,555),在 CCC 和 DDD 中有两个匹配项:

        grp1 成员 grp2 AAA 123 CCC AAA 123 DDD AAA 456 CCC AAA 789 AAA 555 DDD

        如果您希望每个 grp1 有一行,并且成员在字符串中包含所有匹配的 grp2,那么据我所知,您需要在 SQL Server 中使用一些笨拙的 STUFF 技巧。查找“SQL Server 中的 GROUP_CONCAT”以找到所需的技术。

        【讨论】:

          猜你喜欢
          • 2021-11-02
          • 1970-01-01
          • 2014-07-03
          • 1970-01-01
          • 2015-05-23
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多