2010-10-28 28 views
47

Ok, creo que podría pasar por alto algo obvio/simple aquí ... pero necesito escribir una consulta que devuelva solo registros que coincidan con múltiples criterios en la misma columna ...SELECCIONAR con múltiples condiciones WHERE en la misma columna

Mi tabla es una configuración muy simple de enlace para la aplicación de las banderas a un usuario ...

ID contactid flag  flag_type 
----------------------------------- 
118 99   Volunteer 1 
119 99   Uploaded 2 
120 100  Via Import 3 
121 100  Volunteer 1 
122 100  Uploaded 2 

etc ... en este caso verá tanto el contacto 99 y 100 se marcan como tanto "Voluntario" y "Cargado" ...

Lo que necesito poder hacer es devolver esos cont actid sólo que múltiples criterios de coincidencia introducidos a través de un formulario de búsqueda de los ... ContactID tienen que coincidir con TODOS los parámetros elegidos ... en mi cabeza el SQL debe ser algo como:

SELECT contactid 
WHERE flag = 'Volunteer' 
    AND flag = 'Uploaded'... 

... pero que no devuelve nada. .. ¿Qué estoy haciendo mal aquí?

Respuesta

61

Puede utilizar GROUP BY y HAVING COUNT(*) = _:

SELECT contact_id 
FROM your_table 
WHERE flag IN ('Volunteer', 'Uploaded', ...) 
GROUP BY contact_id 
HAVING COUNT(*) = 2 -- // must match number in the WHERE flag IN (...) list 

(suponiendo contact_id, flag es único).

O usar combinaciones:

SELECT T1.contact_id 
FROM your_table T1 
JOIN your_table T2 ON T1.contact_id = T2.contact_id AND T2.flag = 'Uploaded' 
-- // more joins if necessary 
WHERE T1.flag = 'Volunteer' 

Si la lista de banderas es muy largo y hay un montón de partidos, el primero es probablemente más rápido. Si la lista de banderas es corta y hay pocas coincidencias, probablemente encontrará que la segunda es más rápida. Si el rendimiento es una preocupación, intente probar ambos en sus datos para ver cuál funciona mejor.

+1

El problema con JOINs es que si hay más de un registro de un contactid asociado con el indicador "Uploaded", habrá duplicados para las referencias T1. –

4

realmente no se puede ver su tabla, pero la bandera no puede ser "Voluntaria" ni "Cargada". Si tiene varios valores en una columna, puede usar

WHERE flag LIKE "%Volunteer%" AND flag LIKE "%UPLOADED%" 

No es realmente aplicable ver la tabla formateada.

11

Uso:

SELECT t.contactid 
    FROM YOUR_TABLE t 
    WHERE flag IN ('Volunteer', 'Uploaded') 
GROUP BY t.contactid 
    HAVING COUNT(DISTINCT t.flag) = 2 

La clave es que el recuento de t.flag tiene que ser igual al número de argumentos en la cláusula IN.

El uso de COUNT(DISTINCT t.flag) es en caso de que no es una restricción única en la combinación de contactid y la bandera - si no hay ninguna posibilidad de duplicados se puede omitir el DISTINCT de la consulta:

SELECT t.contactid 
    FROM YOUR_TABLE t 
    WHERE flag IN ('Volunteer', 'Uploaded') 
GROUP BY t.contactid 
    HAVING COUNT(t.flag) = 2 
-2

veces no se puede ver el bosque por los árboles :)

Su SQL originales ..

SELECT contactid 
WHERE flag = 'Volunteer' 
    AND flag = 'Uploaded'... 

debe ser:

SELECT contactid 
WHERE flag = 'Volunteer' 
    OR flag = 'Uploaded'... 
+1

No creo que esto arroje los resultados que el OP desea. Los contactos deben coincidir con TODOS los indicadores, no con uno o más de ellos. – Kildareflare

+0

Probé esto y esto no funciona en la MISMA columna –

-1

AND le devolverá una respuesta sólo cuando ambos volunteer y uploaded están presentes en su columna. De lo contrario, devolverá el valor null ...

intentar usar OR en su estado de cuenta ...

SELECT contactid WHERE flag = 'Volunteer' OR flag = 'Uploaded' 
+0

Esto mostrará todas las entradas que son 'Voluntario' O' Cargado' pero quiere entradas que están dos veces y tienen una vez – kero

2

intentar usar esta consulta alternativo:

SELECT A.CONTACTID 
FROM (SELECT CONTACTID FROM TESTTBL WHERE FLAG = 'VOLUNTEER')A , 
(SELECT CONTACTID FROM TESTTBL WHERE FLAG = 'UPLOADED') B WHERE A.CONTACTID = B.CONTACTID; 
0
select contactid ,Count(*) from YOUR_TABLE where flag in ('Volunteer','Uploaded') group by contactid 
having count(*)>1; 
+3

Considere mejorar su respuesta. _ [Las respuestas de solo código pueden caer en "Muy baja calidad" ... y son candidatas a borrarse ... Siempre hemos dicho que no somos una fábrica de códigos. Somos las personas que enseñan a otros a pescar. Las respuestas de solo código alimentan a una persona por un día] (http://meta.stackexchange.com/questions/148272/is-there-any-benefit-to-allowing-code-only-answers-while-blocking-code -lyly-ques) _ – MickyD

-2
select purpose.pname,company.cname 
from purpose 
Inner Join company 
on purpose.id=company.id 
where pname='Fever' and cname='ABC' in (
    select mname 
    from medication 
    where mname like 'A%' 
    order by mname 
); 
0

cambio y OR. Error simple Piense en ello como un simple inglés, quiero seleccionar cualquier cosa que iguale esto o aquello.

-2

su código:

SELECT contactid 
WHERE flag = 'Volunteer' AND flag = 'Uploaded' [...] 

no va a funcionar, porque no declaró el nombre de tabla. la ejecución devolverá un mensaje de error.

y si desea que se muestren ambas consultas de búsqueda, , su código debería verse más o menos así.

SELECT * FROM (your_table_name) WHERE flag = 'Volunteer' OR flag = 'Uploaded'; 

y no como este, ya que siempre devolverá falso SELECT * FROM (your_table_name) DONDE bandera = 'voluntario' y la bandera = 'Subida';

también se puede hacer esto

SELECT * FROM (your_table_name) 
WHERE flag = 'Volunteer' OR flag = 'Uploaded' 
ORDER BY contactid, flag asc; 

(ASC por orden ascendente, también se puede cambiar a la descripción si quieres que se muestre en orden descendente)

6

Considere el uso de INTERSECT así:

SELECT contactid WHERE flag = 'Volunteer' 
INTERSECT 
SELECT contactid WHERE flag = 'Uploaded' 

creo que la solución más logística.

Cuestiones relacionadas