Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: Grupowe where
Forum PHP.pl > Forum > Bazy danych > MySQL
ekstro
Taka tabelka (id1,id2,id3):

Kod
1    1    1
2    1    2
3    1    3
4    2    3
5    3    2
6    3    3
7    4    2
8    4    3
9    5    1
10    5    90
11    6    8


W jaki sposób wybrać rekordy podając jako warunek [id3=1 and id3=2] żeby zwróciło wyłącznie id2 rekordów które zawierają i id3=1 i id3=2 grupując po id2?

Użyłem GROUP_CONCAT:

Kod
SELECT GROUP_CONCAT(
CAST(id3 as CHAR)
) AS aaa FROM doc_tags_links
GROUP BY id2


i załóżmy że podając warunek o którym piszę wyżej otrzymuję tabelę:

Kod
(id3)
1,2
2
2
1


Mogę teraz dać warunek WHERE id3 = '1,2' ... ale wiadomo, takie szukanie to string (choć nie wiem czy MySQL domyślnie nie traktuje tego jako SET) + muszę podać odpowiednią kolejność id bo gdy podam WHERE id3 = '2,1' to wiadomo nie znajdzie mi tych rekordów.

Pojawia się pytanie czy można to rozwiązać jakoś inaczej?
#luq
Nie bardzo rozumiem o co Ci chodzi.

Cytat
podając jako warunek [id3=1 and id3=2]

Taki warunek zawsze jest równy false, chyba że chodzi Ci o to, że istnieją rekordy o id2 = x gdzie id3 = 1 oraz id3 = 2

Zapytanie ma zwracać jedynie id2 = 1, bo tylko ono ma rekordy id3 = 1 i id3 = 2
Kod
1    1    1
2    1    2


Dobrze myślę?
ekstro
Fakt, źle to napisałem: chodziło mi bardziej o warunek [id3=1 or id3=2].

Cytat
Zapytanie ma zwracać jedynie id2 = 1, bo tylko ono ma rekordy id3 = 1 i id3 = 2

Tak smile.gif


Generalnie idea jest taka, że potrzebuję zwrócić rekordy które mają id3=1 i id3=2, ale warunek musi być spełniony razem grupując po id2 ... czyli chcę tylko te rekordy w których jeśli w zbiorach pogrupowanych po id2 występuje id3 równe 1 i równe 2:

Kod
(id1,id2,id3)
1    1    1
2    1    2
3    1    3
-----------
4    2    3
-----------
5    3    2
6    3    3
-----------
7    4    2
8    4    3
-----------
9    5    1
10   5    90
-----------
11    6    8


Czyli podając id3=1 OR id3=2 chcę żeby mi zwróciło id2=1 (bo tu jest spełniony warunek, że w zbiorze (group_by id2) są id o wartości 1 i 2 - w innych występują ALBO id3=1 albo id3=2

Zrobiłem to jak pisałem wcześniej na GROUP_CONCAT, ale zastanawiam się czy jest jakaś lepsza opcja.
Mchl
Kod
SELECT
  t1.id2
FROM
  doc_tags_links AS t1
CROSS JOIN
  doc_tags_links AS t2
USING (id2)
WHERE
  t1.id3 = 1 AND t2.id3 = 2
ekstro
@Mchl: twoje rozwiązanie oczywiście zadziała, ale ma ograniczenie, że musimy podać dwa warunki. Ja potrzebuję mieć możliwość dowolnego podawania ilości warunków. Dzięki za odpowiedź!

Jakieś inne sugestie?
aio
na przykład
  1. SELECT id2 FROM `doc_tags_links` T
  2. WHERE (SELECT MAX(id3=1) * MAX(id3=2) FROM `doc_tags_links` wT WHERE T.id2=wT.id2)
  3. GROUP BY id2

gdzie warunek realizowany jest poprzez sekwencje: MAX(id3=value1) * MAX(id3=value2) * MAX(id3=....etc

PS: w Twoim przykładzie z GROUP_CONCAT musiałbyś jeszcze grupować w podzapytaniu kolumnę id3, bo gdyby w grupie id2 było więcej wystąpień liczby '1' to otrzymywałbyś ciąg np '1,1,2'

Mchl
Niezłe to jest!

Kod
SELECT t.id2
FROM doc_tags_links AS t
INNER JOIN (
  SELECT id2, MAX(id3=1)*MAX(id3=2) AS warunek FROM doc_tags_links GROUP BY id2
) AS sq USING(id2)
WHERE sq.warunek = 1
GROUP BY t.id2
To jest wersja lo-fi głównej zawartości. Aby zobaczyć pełną wersję z większą zawartością, obrazkami i formatowaniem proszę kliknij tutaj.
Invision Power Board © 2001-2025 Invision Power Services, Inc.