Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

> Grupowe where
ekstro
post
Post #1





Grupa: Zarejestrowani
Postów: 12
Pomógł: 0
Dołączył: 11.10.2008

Ostrzeżenie: (0%)
-----


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?

Ten post edytował ekstro 20.03.2010, 10:25:14
Go to the top of the page
+Quote Post
 
Start new topic
Odpowiedzi (1 - 6)
#luq
post
Post #2





Grupa: Zarejestrowani
Postów: 589
Pomógł: 91
Dołączył: 22.05.2008
Skąd: Gliwice

Ostrzeżenie: (0%)
-----


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ę?
Go to the top of the page
+Quote Post
ekstro
post
Post #3





Grupa: Zarejestrowani
Postów: 12
Pomógł: 0
Dołączył: 11.10.2008

Ostrzeżenie: (0%)
-----


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 (IMG:style_emoticons/default/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.

Ten post edytował ekstro 20.03.2010, 10:29:57
Go to the top of the page
+Quote Post
Mchl
post
Post #4





Grupa: Zarejestrowani
Postów: 855
Pomógł: 145
Dołączył: 17.07.2008
Skąd: High Memory Area

Ostrzeżenie: (0%)
-----


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
Go to the top of the page
+Quote Post
ekstro
post
Post #5





Grupa: Zarejestrowani
Postów: 12
Pomógł: 0
Dołączył: 11.10.2008

Ostrzeżenie: (0%)
-----


@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?

Ten post edytował ekstro 23.03.2010, 06:29:34
Go to the top of the page
+Quote Post
aio
post
Post #6





Grupa: Zarejestrowani
Postów: 28
Pomógł: 4
Dołączył: 13.11.2009

Ostrzeżenie: (0%)
-----


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'



Ten post edytował aio 23.03.2010, 12:20:00
Go to the top of the page
+Quote Post
Mchl
post
Post #7





Grupa: Zarejestrowani
Postów: 855
Pomógł: 145
Dołączył: 17.07.2008
Skąd: High Memory Area

Ostrzeżenie: (0%)
-----


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


Ten post edytował Mchl 23.03.2010, 17:14:25
Go to the top of the page
+Quote Post

Reply to this topicStart new topic
2 Użytkowników czyta ten temat (2 Gości i 0 Anonimowych użytkowników)
0 Zarejestrowanych:

 



RSS Aktualny czas: 24.08.2025 - 21:58