2012-07-29 23 views
12

Tengo dos columnas, origen y destino en la tabla Hipervínculo, para almacenar el origen y el destino de los hipervínculos.Seleccionar combinaciones distintas de dos columnas

source | destination 
-------------------- 
    a | b 
    b | c 
    c | d 
    c | b 

Hay dos hipervínculos que involucran tanto byc. La diferencia entre los dos hipervínculos es la dirección del hipervínculo. Sin embargo, mi objetivo es recuperar hipervínculos únicos, sin importar en qué dirección. Por lo tanto, para hipervínculos como de b a c y de c a b, solo quiero seleccionar uno de ellos. Cualquiera haría.

Así que mis resultados debería tener este aspecto:

source | destination 
-------------------- 
    a | b 
    b | c 
    c | d 

Hasta ahora soy capaz de implementar esto en Java, con un poco de procesamiento antes de ejecutar sentencias SQL mediante JDBC. Sin embargo, esto será muy tedioso cuando la mesa se vuelva muy grande.

Me pregunto si de todos modos puedo hacer esto en SQL.

Probé SELECT DISTINCT source,destination FROM Hyperlink pero me devuelve las permutaciones únicas. Necesito las combinaciones únicas.

Gracias!

+2

Si publica ejemplos de código, XML o datos, ** ** POR FAVOR resaltar esas líneas en el editor de texto y haga clic en el botón "samples de código" ('{}') en la barra de herramientas del editor para formatear y sintaxis, ¡resaltarlo! ¡Entonces no necesita ninguna de las etiquetas sucias '
' y ' ', tampoco! –

+2

genial, gracias por la sugerencia! fue difícil tratar de usar las etiquetas desordenadas. – paperclip

+1

gracias por la edición, Arkain! – paperclip

Respuesta

3

Esto es fácilmente alcanzable con la menor() y mayor() del operador, sino como MySQL no soporta verlos es necesario utilizar una construcción CASO para obtener el más pequeño/mayor. Con dos columnas que esto está bien, pero esta solución se vuelve bastante complicado, una vez más columnas están involucrados

select distinct 
      case 
      when source < destination then source 
      else destination 
      end as source, 
      case 
      when source > destination then source 
      else destination 
      end as destination 
from hyperlinks 
+0

Este funciona para mí. Solo trabajo con dos columnas, por lo que esta solución es lo suficientemente buena. ¡Gracias! – paperclip

1

Puede utilizar la unión de dos consultas separadas unirse de este modo:

SELECT 
lhs.source, lhs.destination 
FROM Hyperlink lhs 
LEFT OUTER JOIN Hyperlink rhs 
ON rhs.source = lhs.destination 
WHERE rhs.source IS NULL 
UNION 
SELECT 
lhs.source, lhs.destination 
FROM Hyperlink lhs 
JOIN Hyperlink rhs 
ON rhs.source = lhs.destination 
WHERE rhs.destination <> lhs.source 
ORDER BY source; 

La primera consulta obtiene los enlaces que no tienen el origen como el destino, el segundo obtiene los partidos que tienen como fuente el destino, pero diferentes opuestos. Probablemente no sea la implementación más rápida, pero asegurarse de tener índices en las columnas de origen y destino lo ayudará, ya sea que sea eficaz para usted depende de qué tan grande sea o probable que sea la tabla de hipervínculo.

2

intente lo siguiente consulta:

SELECT DISTINCT source, destination FROM hyperlink 
MINUS 
SELECT destination, source FROM hyperlinks WHERE source < destination; 

Esto funciona para Oracle. Si está utilizando PostgreSQL, DB2 o TSQL, use la palabra clave EXCEPT en lugar de MINUS.

EDITAR: No existe un equivalente de estas palabras clave en MySQL. Tendrás que evitarlo seleccionando los valores según lo sugerido por Jim Riordan. No voy a eliminar mi respuesta en caso de que alguien necesite hacerlo en cualquiera de los otros cuatro principales DBMS.

+0

Estoy usando MySQL, pero gracias por su respuesta. Si no se equivoca, en MySQL debería ser UNIÓN en lugar de MENOS. ¡Gracias de nuevo! – paperclip

+0

@paperclip, hasta donde yo sé, un 'UNION' combina filas de tablas y elimina duplicados. Esto es diferente. 'MINUS' es una operación establecida que elimina una fila de un conjunto para cada fila idéntica en otro conjunto. '(A, B, C) UNIÓN (C, D)' da '(A, B, C, D)'. Pero '(A, B, C) MINUS (C, D)' devuelve '(A, B)'. No puedes simplemente reemplazar una con la otra, tendrías que alterar significativamente las instrucciones SELECT. – toniedzwiedz

0

me trataron esta consulta y funcionó para mí

SELECT table1.Source, table1.Destination FROM dbo.hyperlinks table1 WHERE NOT EXISTS 
(SELECT * FROM hyperlinks table2 WHERE table1.Source = table2.Destination AND table2.Source = table1.Destination) 

UNION 

SELECT TOP 1 table1.Source, table1.Destination FROM hyperlinks table1 WHERE 
    (SELECT COUNT(*) FROM hyperlinks table2 WHERE table1.Source = table2.Destination AND table2.Source = table1.Destination) > 0 
+0

No entiendo su declaración. ¿De dónde viene table2? – paperclip

+0

¡este es un nombre de alias para la tabla de hipervínculos! porque utilicé la tabla de hipervínculos más de una vez en mi consulta, tengo que usar un nombre de alias para ella. Usé test1 y test2. puedes usar cualquier nombre que quieras! – Azade

+0

Oh, lo entiendo ahora. :) – paperclip

Cuestiones relacionadas