2012-12-26 21 views
24

Mam tabeli jak poniżej:MySQL Multiple Gdzie Klauzula

id image_id style_id style_value 
----------------------------------- 
1 45  24  red 
1 45  25  big 
1 47  26  small 
1 45  27  round 
1 49  28  rect 

Chcę wziąć image_id kolumnę jeżeli:

  • style_id = 24 i style_value = red
  • style_id = 25 i style_value = big
  • style_id = 26 i style_value = round

mam zrobić kwerendę tak:

$query = mysql_query("SELECT image_id FROM list WHERE (style_id = 24 AND style_value = 'red') AND (style_id = 25 AND style_value = 'big') AND (style_id = 27 AND style_value = 'round') 

ale nie mogłem dostać żadnego rezultatu. Kiedy robię tę próbkę za pomocą OR, działa dobrze. Ale muszę to zrobić z AND. Ponieważ potrzebuję obrazów id, które są zarówno "czerwone, duże i proste".

Zrobiłem dużo wyszukiwania w Google, ale nie mogłem ukoić żadnego rozwiązania.

Dzięki,

Życzę miłej pracy.

+0

Czy istnieje jakaś zależność między atrybutem style_id a value_value? Oznacza to, że styl_id 24 oznacza "czerwony", a styl_id 25 oznacza "duży"? – mdoyle

+0

Tak, mam inną tabelę o nazwie "style". A styl ma 5-6 różnych opcji. Na przykład: style_id 24 ma 5 różnych opcji (czerwony, zielony, żółty, ...). –

+0

Czy możesz podać listę "SHOW CREATE TABLE" \ G "i" SHOW CREATE TABLE styles \ G ", a także podać kilka przykładowych wierszy z tabeli' styles'? – mdoyle

Odpowiedz

0

To może być to, czego szukasz, chociaż w zależności od tego, ile jest identyfikatorów stylu, byłoby to trudne do implementacji (nie jestem pewien, czy te id stylu są statyczne czy nie). Jeśli tak jest, to nie jest możliwe, co chcesz, ponieważ klauzula WHERE działa na podstawie wiersza do wiersza.

WITH cte as (
    SELECT 
    image_id, 
    max(decode(style_id,24,style_value)) AS style_colour, 
    max(decode(style_id,25,style_value)) AS style_size, 
    max(decode(style_id,27,style_value)) AS style_shape 
    FROM 
    list 
    GROUP BY 
    image_id 
) 
SELECT 
    image_id 
FROM 
    cte 
WHERE 
    style_colour = 'red' 
    and style_size = 'big' 
    and style_shape = 'round' 

http://sqlfiddle.com/#!4/fa5cf/18

+0

Próbowałem w sqlfiddle, ale te wartości nie są statyczne. Muszę więc przekonwertować na wersję dynamiczną. Jeśli nie mogę znaleźć żadnego praktycznego rozwiązania, mogę wypróbować Twoje rozwiązanie. Dzięki Lock. –

6

Nigdy nie będzie uzyskać wynik, jest to prosty błąd logiczny.

Prosi się bazę danych, aby zwrócić wiersz, który ma style_id = 24 AND style_id = 25 AND style_id = 26. Ponieważ 24 to niether 25 ani 26, nie uzyskasz żadnego wyniku.

Musisz użyć OR, to ma sens.

+0

Ale są tam również zarówno image_id (45) => style_id (24), image_id (45) => style_id (25), image_id (45) => style_id (26) ... Oznacza to, że tabela ma 3 różne wiersze z tym samym image_id. –

+0

Powinieneś więc sprawdzić także ten sam image_id. Nie jestem całkiem pewien, jaki jest cel twojego SQL. – akashivskyy

37

myślę, że jesteś po to:

SELECT image_id 
FROM list 
WHERE (style_id, style_value) IN ((24,'red'),(25,'big'),(27,'round')) 
GROUP BY image_id 
HAVING count(distinct style_id, style_value)=3 

Nie można używać AND, ponieważ wartości te nie mogą być 24 red i 25 big i 27 round w tym samym czasie w tym samym rzędzie, ale trzeba sprawdź obecność style_id, style_value w wielu wierszach, pod tym samym image_id.

W tym zapytaniu używam IN (które w tym konkretnym przykładzie jest równoważne OR) i liczę różne wiersze, które pasują do siebie. Jeśli 3 różne wiersze są zgodne, oznacza to, że wszystkie 3 atrybuty są obecne dla tego image_id, a moje zapytanie zwróci je.

+0

Nigdy nie wiedziałem, że możesz zgrupować takie klauzule. Sprytny. – erich2k8

9
SELECT a.image_id 
FROM list a 
INNER JOIN list b 
    ON a.image_id = b.image_id 
    AND b.style_id = 25 
    AND b.style_value = 'big' 
INNER JOIN list c 
    ON a.image_id = c.image_id 
    AND c.style_id = 27 
    AND c.style_value = 'round' 
WHERE a.style_id = 24 
    AND a.style_value = 'red' 
+0

dzięki. Oto, czego potrzebuję. Zrobione. Miłej pracy. –

0
select unique red24.image_id from 
( 
    select image_id from `list` where style_id = 24 and style_value = 'red' 
) red24 
inner join 
( 
    select image_id from `list` where style_id = 25 and style_value = 'big' 
) big25 
on red24.image_id = big25.image_id 
inner join 
( 
    select image_id from `list` where style_id = 27 and style_value = 'round' 
) round27 
on red24.image_id = round27.image_id 
+0

dzięki. Twój kod działa bardzo dobrze. Po prostu usuwam "unikalny" parametr zgodnie z moimi potrzebami. Teraz wszystko jest w porządku. Jeszcze raz dziękuję i życzę miłej pracy. –

0

mogą używać tej kwerendy nie dostaniesz żadnego rezultatu lub pusty wynik. Musisz użyć OR zamiast AND w zapytaniu jak poniżej.

$query = mysql_query("SELECT image_id FROM list WHERE (style_id = 24 AND style_value = 'red') OR (style_id = 25 AND style_value = 'big') OR (style_id = 27 AND style_value = 'round'); 

Wypróbuj to zapytanie.