2012-09-27 6 views
5

Ésta me ha tenido perplejo de las últimas horas y en este momento creo que necesito un poco de ayuda ...Grupo por la columna A, pero la comparación de la columna B

que necesitan para comparar varios grupos de una sola tabla y para identificar dónde coinciden los artículos enumerados en la columna B Por ejemplo: -

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

quiero 'John' y 'David' devueltos porque sus artículos en el partido B col. Espero que esto tenga sentido! ¡Gracias de antemano! G

+2

¿qué versión de sql-server? – Taryn

+0

SQL Server 2008 Express – user1704276

+0

Ayuda a tener la salida esperada definida de manera muy explícita. Tienes entrada de muestra arriba. Intente escribir resultados de muestra en el formato exacto que desee. –

Respuesta

6

Aquí está el SQL Fiddle para esta solución, para que pueda jugar con ella.

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

¡gran solución! – RomanKonz

+0

si agrega estos registros: Tim .... Apple Jim .... Naranja Jim .... Plátano Agrega a Jim al conjunto de devolución. – jTC

+1

@JTC Gracias. arreglado ahora. Es una revisión por pares para usted :) – RichardTheKiwi

0

Todas las personas que tienen un elemento en la columna B que se corresponde a más de la persona (estoy asumiendo que busca posiblemente algo más que 2 partidos?):

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 coincide con ColA2 si:
Recuento (ColA1) = Recuento (ColA2) = Recuento (ColA1 x ColA2)

Este enfoque intenta optimizar la velocidad de consulta.

Materialice el conteo sin procesar ya que se usa más de una vez y puede declarar un PK.
(un CTE es solo una sintaxis y se evalúa)

donde RA.rawcount = RB.rawcount solo permite evaluar la unión si los recuentos son iguales. Y el plan de consulta indica que se realiza primero.

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 
Cuestiones relacionadas