2012-09-27 20 views
5

Ten został już mnie zakłopotany przez ostatnie kilka godzin, a na tym etapie Chyba potrzebuje pomocy ...Grupa kolumnie A, ale porównując kolumna B

muszę porównać wiele grup z jednej tabeli i aby określić, gdzie pozycje wymienione w kolumnie B zgadzają się. Na przykład: -

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

Chcę, aby "John" i "David" wrócili, ponieważ ich przedmioty w col B pasują. Mam nadzieję, że to ma sens! Z góry dziękuję! G

+2

jaka wersja serwera sql? – Taryn

+0

SQL Server 2008 Express – user1704276

+0

Pomaga bardzo wyraźnie określić oczekiwane wyniki. Masz przykładowe wejście powyżej. Spróbuj zapisać przykładowe dane wyjściowe w formacie, który chcesz. –

Odpowiedz

6

Oto SQL Fiddle dla tego rozwiązania, dzięki czemu można grać samodzielnie.

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 
+0

świetne rozwiązanie! – RomanKonz

+0

jeśli dodasz te zapisy: Tim .... Apple Jim .... Orange Jim .... Banana Dodaje Jim do zestawu zwrotu. – jTC

+1

@JTC Dzięki. Naprawiono teraz. To jest recenzja dla Ciebie :) – RichardTheKiwi

0

wszystkich ludzi, którzy mają pozycję w kolumnie B, które jest dopasowane do więcej niż na osobę (Zakładam, że szukasz ewentualnie więcej niż tylko 2 mecze):

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 
0

ColA1 pasuje do ColA2, jeśli:
Count (ColA1) = Count (ColA2) = Count (ColA1 x ColA2)

Podejście to próbuje zoptymalizować prędkość zapytania.

Wykonaj materializację liczby surowej, ponieważ jest ona używana więcej niż jeden raz i może zadeklarować PK.
(CTE jest po prostu składnią i jest oceniany)

Miejsce, w którym RA.rawcount = RB.rawcount pozwala ocenić tylko sprzężenie, jeśli liczba jest równa. Plan kwerendy wskazuje, że jest wykonywany jako pierwszy.

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 
Powiązane problemy