2012-07-08 29 views
7

Mi mesa:columna Compruebe si hay un valor único

id attribute 
1 2 
1 2 
2 3 
2 4 
5 1 
5 1 
6 3 
6 3 
6 5 

Ahora quiero sólo para salida de los id con attribute, si el atributo es la misma para cada id.

En esta tabla muestra, la salida sería

id attribute 
1 2 
5 1 

Respuesta

7

podría utilizar este enfoque:

SELECT DISTINCT id, attribute 
FROM test t1 
WHERE (SELECT count(DISTINCT attribute) 
     FROM test t2 
     WHERE t2.id = t1.id) = 1 

Un mejor enfoque podría ser:

SELECT 
    DISTINCT t1.id, t1.attribute 
FROM 
    test t1, 
    (
     SELECT 
     id, 
     count(DISTINCT attribute) COUNT 
     FROM 
     test 
     GROUP BY 
     id 
     HAVING 
     COUNT = 1 
    ) t2 
WHERE 
    t1.id = t2.id 
+1

Este método es muy ineficiente, porque va a ejecutar esa consulta interna para cada fila en prueba. Esto comenzará a afectar el rendimiento bastante rápido a medida que la mesa crezca. – Braiba

+0

@ Braya: Tienes razón. El segundo enfoque podría reducir la complejidad. –

+0

La consulta interna es funcionalmente la misma que la primera de Ycubcube; No veo lo que la consulta externa agrega aquí, ¿o me falta algo? – Braiba

1

Bueno, yo En su lugar, use el siguiente enfoque:

 SELECT DISTINCT ta.id, ta.attribute 
     FROM test ta 
    LEFT JOIN test tb 
     ON ta.id = tb.id AND ta.attribute <> tb.attribute 
     WHERE tb.id IS NULL; 

... como suelo tender al menos a intentar reemplazar consultas anidadas con tablas unidas. Por supuesto, si su mesa es pequeña, no importará mucho.

+0

Las consultas anidadas están bien siempre que se una a ellas, en lugar de ponerlas en una cláusula SELECT/WHERE/ON. Sin embargo, unirse a una mesa sobre sí mismo no es mucho mejor; el tiempo de procesamiento aún aumentará exponencialmente a medida que la tabla crezca. – Braiba

8
SELECT id, MIN(attribute) AS attribute 
FROM test 
GROUP BY id 
HAVING COUNT(DISTINCT attribute) = 1 ; 

o:

SELECT id, MIN(attribute) AS attribute 
FROM test 
GROUP BY id 
HAVING MIN(attribute) = MAX(attribute) ; 

Yo esperaría que la última versión a ser muy eficiente, con un índice en (id, attribute)

+0

+1 para la forma más eficiente de hacerlo. El MIN = MAX es realmente inteligente; Recordaré ese truco para el futuro. – Braiba

+0

Me gusta mucho esta respuesta también. ¿Cuál es la etiqueta en SO? ¿Primero llega primer servicio o mejor respuesta? –

+0

@Terry Uhlang La mejor respuesta tiene más sentido para mí, ya que será la primera que verán otros usuarios con el mismo problema cuando busquen esta pregunta. – Braiba

Cuestiones relacionadas