2010-10-28 14 views
47

OK, myślę, że może być przeoczeniem czegoś oczywistego/prostego tutaj ... ale muszę napisać zapytanie, które zwraca tylko rekordy, które pasują do wielu kryteriów w tej samej kolumnie ...WYBIERANIE z wieloma warunkami WHERE na tej samej kolumnie

Moja tabela jest bardzo prosta konfiguracja powiązanie stosowania flagi użytkownikowi ...

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 

itd ... w tym przypadku zobaczysz zarówno styk 99 i 100 są oznaczone jako „zarówno wolontariusz” i "Przesłane" ...

Muszę być w stanie zwrócić te wartości actid tylko spełniające wiele kryteriów wprowadzone poprzez formularz wyszukiwania ... to ContactID mają dopasować wszystkie wybrane flagi w mojej głowie ... SQL powinien wyglądać mniej więcej tak:

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

ale ... że nic nie zwraca. .. Co ja tu robię źle?

Odpowiedz

61

Można użyć GROUP BY i 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 

(zakładając contact_id, flag jest wyjątkowy).

lub użyj dołącza:

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' 

Jeżeli lista jest bardzo długa flagi i istnieje wiele meczów pierwszy jest prawdopodobnie szybciej. Jeśli lista flag jest krótka i jest kilka dopasowań, prawdopodobnie okaże się, że druga jest szybsza. Jeśli wydajność jest problemem, spróbuj przetestować oba dane, aby zobaczyć, który działa najlepiej.

+1

Problem związany z powiązaniami JOIN polega na tym, że istnieje więcej niż jeden rekord kontaktu kontaktowego skojarzonego z flagą "Przesłane", w przypadku odniesień T1 wystąpią duplikaty. –

4

Naprawdę nie widzę twojego stołu, ale flaga nie może być jednocześnie "Wolontariuszem" i "Wgraniem". Jeśli masz wiele wartości w kolumnie, możesz nie używać naprawdę niezastąpionego widoku w sformatowanej tabeli.

11

Zastosowanie:

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

Kluczową rzeczą jest to, że liczenie t.flag musi być równa liczbie argumentów w klauzuli IN.

Zastosowanie COUNT(DISTINCT t.flag) w przypadku nie jest UNIQUE na połączeniu ContactID i flagi - jeśli nie ma szans duplikatów można pominąć odróżnieniu od zapytania:

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

Czasami nie można zobaczyć drewna na drzewach :)

oryginalna SQL ..

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

powinno być:

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

Nie wierzę, że to zwróci wyniki pożądane przez PO. Identyfikatory contactId muszą pasować do WSZYSTKICH flag, a nie do jednej lub więcej z nich. – Kildareflare

+0

Wypróbowałem to i to nie działa w kolumnie SAME –

-1

AND zwróci Ci odpowiedź tylko wtedy, gdy oba volunteer i uploaded są obecne w kolumnie. W przeciwnym razie zwróci wartość null ...

spróbuj OR w wyciągu ...

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

To pokaże wszystkie wpisy, które są "Wolontariuszem" LUB "Przesłane", ale chce wpisów, które są dwa razy i mają raz jeden. – kero

2

Spróbuj skorzystać z tej alternatywnej zapytanie:

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

Rozważ poprawę odpowiedzi. _ [Odpowiedzi tylko na kod mogą należeć do "Bardzo niskiej jakości" ... i są kandydatami do usunięcia ... Zawsze twierdziliśmy, że nie jesteśmy fabryką kodu. Jesteśmy ludźmi, którzy uczą innych łowić ryby. Tylko kod odpowiada tylko na karmienie danej osoby przez jeden dzień] (http://meta.stackexchange.com/questions/148272/is-there-any-benefit-to-allowing-code-only-answers-while-blocking-code -only-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

zmiany i OR. Prosty błąd. Pomyśl o tym jak o zwykłym angielskim, chcę wybrać wszystko, co jest równe temu lub tamto.

-2

kod:

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

nie będzie działać, bo nie ogłoszono nazwę tabeli. wykonanie zwróci komunikat o błędzie.

Jeśli chcesz, aby oba zapytania wyszukiwania wyświetlały się, Twój kod powinien wyglądać mniej więcej tak.

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

i nie podoba mi się to, bo to zawsze return false SELECT * FROM (your_table_name) GDZIE flag = 'Wolontariusz' i flaga = 'Dodane';

można też zrobić to

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

(ASC w porządku rosnącym, można również zmienić na opis produktu, jeśli chcesz go wyświetlić w kolejności malejącej)

6

Rozważ użycie przecinają tak:

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

Myślę, że to najbardziej logistyczne rozwiązanie.

Powiązane problemy