按列A分组但比较B列

时间:2012-09-27 19:08:56

标签: sql sql-server sql-server-2008 tsql

这个让我在最后几个小时难过,在这个阶段我觉得我需要一些帮助......

我需要比较单个表中的多个组,并确定col B中列出的项目匹配的位置。例如: -

Col A...............Col B
John................Apple
John................Orange
John................Banana
Mary................Orange
Mary................Strawberry
David...............Apple
David...............Orange
David...............Banana

我希望'John'和'David'返回,因为他们在col B中的项目匹配。希望这是有道理的! 提前致谢! ģ

3 个答案:

答案 0 :(得分:6)

这是此解决方案的SQL Fiddle,因此您可以自己玩它。

 select A.ColA Person1, B.ColA Person2
    from (select ColA, count(ColB) CountBs
          from tbl
          group by ColA) G1
    join (select ColA, count(ColB) CountBs
          from tbl
          group by ColA) G2 on G1.ColA < G2.ColA
                           and G1.CountBs = G2.CountBs
    join tbl A on A.ColA = G1.ColA
    join tbl B on B.ColA = G2.ColA and A.ColB = B.ColB
group by A.ColA, B.ColA, G1.CountBs
having count(distinct A.ColB) = G1.CountBs

-- subqueries G1 and G2 are the same and count the expected colB's per colA
-- G1 and G2 are joined together to get the candidate matches
--    of ColA with the same number of ColB's
-- we then use G1 and G2 to join into tbl, and further join
--    between A and B where the ColB's match
-- finally, we count the matches between A and B and make sure the counts match
--    the expected count of B's for the pairing

答案 1 :(得分:0)

所有在b栏中都有一项与人匹配的项目的人(我假设您正在寻找的可能不仅仅是2场比赛?):

SELECT tableName.ColA, tableName.ColB
FROM (SELECT ColB
    FROM tableName
    GROUP BY ColB
    HAVING COUNT(1) > 1) fruits
INNER JOIN tableName ON fruits.ColB = tableName.ColB
ORDER BY tableName.ColB, tableName.ColA

答案 2 :(得分:0)

如果出现以下情况,ColA1与ColA2匹配:
计数(ColA1)=计数(ColA2)=计数(ColA1 x ColA2)

此方法尝试优化查询速度。

将原始计数物化为多次使用,并且可以声明PK (CTE只是语法并被评估)

RA.rawcount = RB.rawcount的位置仅允许在计数相等时评估连接。查询计划表明它首先执行。

create table #rawcount
(ColA varchar(50) not null primary key, rawcount int  not null)  
insert into #rawcount
select   [ColA], COUNT(*) as  [rawCount]
from     [tbl]
group by [ColA]
order by [ColA]

select a.ColA as ColA1, b.ColA as ColA2, COUNT(*) [matchcount]
from tbl A
join tbl B
 on  a.ColB = b.ColB 
 and a.ColA < b.ColA
join #rawcount RA 
 on  RA.ColA = A.ColA
join #rawcount RB 
 on  RB.ColA = B.ColA
where RA.rawcount = RB.rawcount  -- only evaluate if count same
group by a.ColA, b.ColA, RA.rawcount
having COUNT(*) = RA.rawcount