2012-07-02 30 views
7

Tengo una tabla con dos columnas:Mysql Seleccione pares recíprocos de registros, sin duplicados

  1. person_id
  2. person_id con quien primero campo id es en cooperación

tengo que seleccionar todo pares de cooperación, es fácil pero en lo que es el problema: tabla tiene datos como: 987 - 102, 103 - 104, 104 - 103, 21 - 102. Como resultado con tales datos debería tener 3 pares de cooperación 987 - 102, 103-104, 21-102, como ve 103 - 104 y 104 - 103 registros tienen la misma lógica, ¿cómo puedo evitar la duplicación de ellos. ¿Alguna idea?

Gracias, y mis mejores deseos. Anton

+0

nosotros su estructura de tabla muestran –

+0

int person_id (10), int question_id (10) de texto TEXT_ANSWER, creo segundo colomn no es necesario, ya que en esa pregunta, lo uso en la cláusula WHERE –

Respuesta

10

Usted podría utilizar LEAST() y GREATEST() funciones de MySQL, junto con DISTINCT:

SELECT DISTINCT LEAST(a, b), GREATEST(a, b) FROM mytable 
+1

Si sólo tiene un par de ' (2,1) 'lo generará como' (1,2) ' – alfasin

+1

@alfasin: la descripción del problema implica que son equivalentes. De lo contrario, el PO debería aclarar cómo se decidió cuál de '(103,104)' y '(104,103)' debería conservarse y descartarse. – eggyal

+0

@eggyall: está en lo cierto, no se da ninguna indicación sobre cómo se hizo la determinación de que '(103,104)' debería ser devuelto en lugar de '(104,103)'. Pero preservar el orden de los elementos en los otros "pares" podría ser importante en algunos casos. Como un ejemplo, si este conjunto de resultados (subconsulta) se une nuevamente a la tabla, para obtener otras columnas de la fila. La conclusión es que el orden de los elementos en el par podría ser importante (y no se nos dice que no lo es). La especificación brinda un ejemplo de conjunto de resultados. Su consulta arroja un conjunto de resultados que difiere de la especificación. – spencer7593

3

Si preservar el orden de los elementos en cada "par" es no importante, ver la respuesta de eggyal. Esa consulta devuelve un conjunto de resultados que es ligeramente diferente al que usted especificó, devuelve el par 102-987 en lugar de 987-102. También elimina los pares "duplicados" que aparecen en la tabla.

Si preservar el orden de los elementos en cada par es importante, y desea devolver el "menor - más grande" en lugar de "más grande - más pequeño" cuando ambos pares "coincidentes" están presentes, el puede usar algo como esto:

SELECT c.col1, c.col2 
    FROM mytable c 
    LEFT 
    JOIN mytable d ON d.col1 = c.col2 AND d.col2 = c.col1 AND d.col1 <> d.col2 
WHERE (d.col1 IS NULL OR d.col1 > c.col1) 

Para eliminar todos los pares duplicados y los pares de "igualación", añadir una cláusula GROUP BY o la palabra clave DISTINCT, por ejemplo,

SELECT c.col1, c.col2 
    FROM mytable c 
    LEFT 
    JOIN mytable d ON d.col1 = c.col2 AND d.col2 = c.col1 AND d.col1 <> d.col2 
WHERE (d.col1 IS NULL OR d.col1 > c.col1) 
GROUP BY c.col1, c.col2 

NOTAS:

SQL violín aquí: http://sqlfiddle.com/#!2/1d9e7/1 y aquí: http://sqlfiddle.com/#!2/1d9e7/2

Los operadores de comparación no son nulos de fallos, es posible que no devuelven el conjunto de resultados que desea cuando sea col1 o col2 contiene un valor NULL (La consulta podría modificarse para manejar valores NULL para col1 y/o col2). Como está escrito, ambas consultas regresarían, por ejemplo, tanto (1,NULL) como (NULL,1) si esos "pares" "coincidentes" están en la tabla. (Todo se reduce a la cuestión de si desea considerar valores NULOS para coincidir o no).

También tenga en cuenta que ambas consultas devolverán filas donde col1=col2.

Tenga en cuenta que la primera consulta NO elimina las filas "duplicadas" que existen en la tabla. Es decir, si un "par" duplicado, por ejemplo, (202,101) aparece en dos filas diferentes, se devolverán ambos (a menos que la consulta devuelva al menos una fila con un par "coincidente": (101,202).)

No estaba claro qué conjunto de resultados quería devolver en esos casos, por lo que la primera consulta muestra el patrón para eliminar SOLAMENTE las filas (larger,smaller) cuando un par coincidente (smaller,larger) está en el conjunto de resultados.

La segunda consulta elimina TODOS los duplicados y pares "coincidentes".

Cuestiones relacionadas