Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

> [MySQL] Wybieranie rekordów
parzol
post
Post #1





Grupa: Zarejestrowani
Postów: 135
Pomógł: 1
Dołączył: 7.05.2005

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


Witam.

Mam tabele:

id | atrakcja
==========
1 | aaaa
2 | bbbb

id | dom
======
1 | Basia
2 | Gosia
3 | Zosia

dom_id | atrakcja_id
==============
1 | 1
1 | 2
2 | 2
3 | 1

I jak wyświetlić nazwy domów dla których atrakcja_id przyjmuje wartość zarówno 1 jak i 2 (czyli w naszym przypadku zwroci tylko dom Basia) ?
Go to the top of the page
+Quote Post
 
Start new topic
Odpowiedzi (1 - 13)
nevt
post
Post #2





Grupa: Przyjaciele php.pl
Postów: 1 595
Pomógł: 282
Dołączył: 24.09.2007
Skąd: Reda, Pomorskie.

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


zakładając, że twoje tabelki to: `domy`, `atrakcje` i `domy_atrakcje`:
  1. SELECT `dom` FROM `domy_atrakcje`LEFT JOIN `domy` ON `id` = `dom_id` GROUP BY `dom_id` HAVING COUNT(`atrakcja_id`) > 1;


--------------------

-
Oh no, my young coder. You will find that it is you who are mistaken, about a great many things... -
Go to the top of the page
+Quote Post
pest
post
Post #3





Grupa: Zarejestrowani
Postów: 78
Pomógł: 15
Dołączył: 10.12.2007
Skąd: Lublin

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


Nie dokładnie - zabrakło wyboru konkretnych atrakcji - przy większej liczbie atrakcji, wybierałoby jakikolwiek dom, który ma 2 lub więcej różnych atrakcji.

zakładając tabele:
`domy` (pola: `dom_id`, `dom`),
`atrakcje` (pola: `atrakcja_id`, `atrakcja`),
`domy_atrakcje` (pola: `dom_id`, `atrakcja_id`)

  1. SELECT `d`.`dom_id`, `dom`
  2. FROM `domy` da
  3. LEFT JOIN `domy_atrakcje` d ON `d`.`dom_id` = `da`.`dom_id`
  4. WHERE `atrakcja_id` IN (1,2)
  5. GROUP BY `d`.`dom_id`
  6. HAVING COUNT(`atrakcja_id`)=2;
Go to the top of the page
+Quote Post
parzol
post
Post #4





Grupa: Zarejestrowani
Postów: 135
Pomógł: 1
Dołączył: 7.05.2005

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


Chyba się źle zrozumieliśmy nevt. Twój kod wyrzuca mi wszystkie nazwy domów w bazie. A nie o to chodziło.

pest - dzięki. Działa.

Ten post edytował parzol 4.03.2008, 10:59:50
Go to the top of the page
+Quote Post
nevt
post
Post #5





Grupa: Przyjaciele php.pl
Postów: 1 595
Pomógł: 282
Dołączył: 24.09.2007
Skąd: Reda, Pomorskie.

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


Cytat
Twój kod wyrzuca mi wszystkie nazwy domów w bazie. A nie o to chodziło.

NIEMOŻLIWE - sprawdzałem. Pokaż, dane źródłowe, pokaż wyniki i pokaż jakiem naprawdę kodem się posłużyłeś ?


--------------------

-
Oh no, my young coder. You will find that it is you who are mistaken, about a great many things... -
Go to the top of the page
+Quote Post
parzol
post
Post #6





Grupa: Zarejestrowani
Postów: 135
Pomógł: 1
Dołączył: 7.05.2005

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


Pest ci odpisał dlaczego to jest źle.

Jeszcze jedno pytanie. Bo kiedy dałem samo zapytanie wszystko działało pięknie. Ale teraz muszę to podczepić pod istniejące większe zapytanie. Wygląda to tak:

  1. SELECT r.id AS room_id, r.name AS room_name, p.id AS property_id, p.name AS property_name, c.name AS city, region.name AS region, p.standard, rg.file, MIN(rp.price) AS min_price, MAX(rp.price) AS max_price, GROUP_CONCAT(DISTINCT CONCAT(a.name, '*', a.icon) ORDER BY a.name SEPARATOR '|') AS attractions, r.description AS opis, r.bedroom_number AS l_sypialni, r.room_number AS l_pokoi, GROUP_CONCAT(DISTINCT CONCAT(t.name) ORDER BY t.name SEPARATOR '|') AS typ FROM room r LEFT JOIN property p ON r.property_id=p.id LEFT JOIN room_gallery rg ON rg.room_id=r.id LEFT JOIN room_price rp ON rp.room_id=r.id LEFT JOIN region ON p.region_id=region.id LEFT JOIN city c ON p.city_id=c.id LEFT JOIN property_attraction pa ON p.id=pa.property_id LEFT JOIN attraction a ON pa.attraction_id=a.id AND (a.is_active=1 OR a.is_active IS NULL) LEFT JOIN property_category pc ON p.id=pc.property_id LEFT JOIN room_type rt ON rt.room_id=r.id LEFT OUTER JOIN type t ON rt.type_id=t.id AND (t.is_active=1 OR t.is_active IS NULL) WHERE pa.attraction_id IN(1,9) GROUP BY pa.property_id HAVING COUNT(attraction_id)=2 GROUP BY room_id ORDER BY p.is_promoted DESC;



I oczywiście wywala błąd bo są dwa GROUP BY. Jak to zapisać żeby działało?
Kod bez klauzuli WHERE działa i wyrzuca wszystkie obiekty. A ja chce tylko te obiekty gdzie atrakcja ma np. ID = 1 i 9.

PS. GROUP BY pa.property_id, room_id nie działa.

Ten post edytował parzol 4.03.2008, 15:01:54
Go to the top of the page
+Quote Post
nevt
post
Post #7





Grupa: Przyjaciele php.pl
Postów: 1 595
Pomógł: 282
Dołączył: 24.09.2007
Skąd: Reda, Pomorskie.

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


Cytat
Pest ci odpisał dlaczego to jest źle.

Nieprawda - Pest wcale nie zakwestionował mojego rozwiązania tylko zaproponował bardziej szczegółowe rozwiązanie. To ty napisałeś że zwraca ci wszystkie rekordy z bazy co jest KŁAMSTWEM gdyż sprawdzałem to zapytanie na strukturze i danych które zamieściłeś w wątku.

Co do kolejnego problemu - cóż - poczekajmy na wypowiedź Pesta - po co mam się niepotrzebnie denerwować - powodzenia smile.gif

Ten post edytował nevt 4.03.2008, 14:43:40


--------------------

-
Oh no, my young coder. You will find that it is you who are mistaken, about a great many things... -
Go to the top of the page
+Quote Post
parzol
post
Post #8





Grupa: Zarejestrowani
Postów: 135
Pomógł: 1
Dołączył: 7.05.2005

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


Spokojnie bez nerwów party.gif

Kod
mysql> SELECT p.name FROM property_attraction pa LEFT JOIN property p ON p.id=pa.property_id GROUP BY pa.property_id HAVING COUNT(pa.attraction_id) >1;
+---------------------+
| name                |
+---------------------+
| bella               |
| Supeeroo Vialnowa   |
| Relais santa chiara |
| La Collegiata       |
| Palazzo Mannaioni   |
| Il Borgo La Bagnaia |
+---------------------+
6 rows in set (0.00 sec)


Poza tym u ciebie w kodzie nie było chociażby klauzuli mówiącej o wybraniu konkretnych atrakcja_id więc już założenia są niespełnione.
Tak czy siak kod pest niezależnie działa tak jak chciałem.

Teraz potrzebuje pomocy jak to podpiąć pod to długie zapytanie. Ktoś pomoże? guitar.gif Z góry dzięki.

Ten post edytował parzol 4.03.2008, 17:42:45
Go to the top of the page
+Quote Post
pest
post
Post #9





Grupa: Zarejestrowani
Postów: 78
Pomógł: 15
Dołączył: 10.12.2007
Skąd: Lublin

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


Sorki za zamieszanie, nie o to mi chodziło. Oczywiście SQL podany przez nevt był dobry, do tamtych danych, ja go uszczegółowiłem - korzystając z tego co on napisał.

Co do długiego zapytania:
Tak jak już pisałem w PM zapytanie jest dość masakryczne, ale skoro wszystko jest potrzebne i taka jest konstrukcja tabel...
Lepiej dać kilka enterów do SQL'a, żeby było szybciej i prościej.

Nie będę analizował może całej struktury tabel, więc tylko ta zmiana w GROUP BY, jeśli nie będzie działało, to napisz jeszcze (bardzo możliwe, że może być coś jeszcze, nawet jak będzie dawało wyniki, to nie daję głowy, że o takie wyniki ci chodzi).

Pozatym, że nie wiem czy w ogóle mogą być 2x GROUP BY do jednego SELECT'a, to jeszcze był jeden problem taki, że `room_id` masz w kilku tabelach i nie podałeś, z której z nich to room_id było.

  1. SELECT r.id AS room_id,
  2. r.name AS room_name,
  3. p.id AS property_id,
  4. p.name AS property_name,
  5. c.name AS city,
  6. region.name AS region,
  7. p.standard,
  8. rg.file,
  9. MIN(rp.price) AS min_price,
  10. MAX(rp.price) AS max_price,
  11. GROUP_CONCAT(
  12. DISTINCT CONCAT(a.name, '*', a.icon)
  13. ORDER BY a.name SEPARATOR '|'
  14. ) AS attractions,
  15. r.description AS opis,
  16. r.bedroom_number AS l_sypialni,
  17. r.room_number AS l_pokoi,
  18. GROUP_CONCAT(
  19. DISTINCT CONCAT(t.name)
  20. ORDER BY t.name SEPARATOR '|'
  21. ) AS typ
  22. FROM room r
  23. LEFT JOIN property p ON r.property_id=p.id
  24. LEFT JOIN room_gallery rg ON rg.room_id=r.id
  25. LEFT JOIN room_price rp ON rp.room_id=r.id
  26. LEFT JOIN region ON p.region_id=region.id
  27. LEFT JOIN city c ON p.city_id=c.id
  28. LEFT JOIN property_attraction pa ON p.id=pa.property_id
  29. LEFT JOIN attraction a ON pa.attraction_id=a.id AND (a.is_active=1 OR a.is_active IS NULL)
  30. LEFT JOIN property_category pc ON p.id=pc.property_id
  31. LEFT JOIN room_type rt ON rt.room_id=r.id
  32. LEFT OUTER JOIN type t ON rt.type_id=t.id AND (t.is_active=1 OR t.is_active IS NULL)
  33. WHERE pa.attraction_id IN(1,9)
  34. GROUP BY r.id, pa.property_id
  35. HAVING COUNT(attraction_id)=2
  36. ORDER BY p.is_promoted DESC;


Ten post edytował pest 4.03.2008, 17:47:10
Go to the top of the page
+Quote Post
parzol
post
Post #10





Grupa: Zarejestrowani
Postów: 135
Pomógł: 1
Dołączył: 7.05.2005

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


Dzięki za zainteresowanie. room_id to r.id oczywiście.
Ten kod nic nie wyrzuca. Nie ma błędów tylko po prostu "Empty set", a powinno poprawnie wyrzucić jeden obiekt.

sadsmiley02.gif
Go to the top of the page
+Quote Post
phpion
post
Post #11





Grupa: Moderatorzy
Postów: 6 072
Pomógł: 861
Dołączył: 10.12.2003
Skąd: Dąbrowa Górnicza




Już o tym rozmawialiśmy ale przedstawię mój pomysł na forum. Może komuś się przyda, a może i usłyszę jakieś opinie (za i przeciw).
Cytat(parzol @ 4.03.2008, 03:08:11 ) *
Witam.

Mam tabele:

id | atrakcja
==========
1 | aaaa
2 | bbbb

id | dom
======
1 | Basia
2 | Gosia
3 | Zosia

dom_id | atrakcja_id
==============
1 | 1
1 | 2
2 | 2
3 | 1

Ja bym zburzył nieco zasady tworzenia baz danych (postacie normalne) i do tabeli z domami dodał kolumnę "attractions", która wyglądałaby dla tego przykładu w ten sposób:
Kod
id | dom   | attractions
=======================
1  | Basia | 1,2
2  | Gosia | 2
3  | Zosia | 1

czyli zawierałaby id atrakcji z tabeli "dom_atrakcja" dla danego domu. Ważne aby id były posortowane (czyli 1,2, a nie 2,1). Później w wyszukiwarce przesyłamy zaznaczone atrakcje w tablicy i łączymy np. implode(',', $_POST['attractions']) do ciągu x,y,z,* po czym możemy sprawdzić, który dom pasuje do zaznaczonych atrakcji poprzez zwykłe LIKE attrations="%$polaczone%". Rozwiązanie wydaje mi się prostsze i wydajniejsze.

Kwestia po co tworzyć więc tabelę "dom_atrakcja". Ano po to aby przy wyświetlaniu danego obiektu łatwo (1 proste zapytanie z joinem) wyświetlić jego atrakcje. Czyli z dodatkowej kolumny korzystamy tylko przy wyszukiwaniu, a przy wyświetlaniu szczegółów obiektu korzystamy już z tej "standardowej".

Aktualizację pola można robić w PHP ale w sumie chyba lepiej/wygodniej napisać do tego triggera.

To mój pomysł guitar.gif

Ten post edytował phpion 7.03.2008, 09:20:40
Go to the top of the page
+Quote Post
parzol
post
Post #12





Grupa: Zarejestrowani
Postów: 135
Pomógł: 1
Dołączył: 7.05.2005

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


Wspaniały pomysł phpionie yahoo.gif

Nowatorsko, odważnie ale nie działa w każdym przypadku !

Nie przewidziałeś drobnej sytuacji kiedy ciąg atrakcji ma postać 1_2_3_9 a ktoś wyszuka według 1_9.
Ale to szczegóły. Wystarczy te '_' usunąć (są zbędne a wręcz niepożądane!) i wyszukiwać tak: LIKE("%1%9%").

Jednak za samą idee gratki i wielkie dzięki! wub.gif

Ten post edytował parzol 7.03.2008, 12:58:42
Go to the top of the page
+Quote Post
phpion
post
Post #13





Grupa: Moderatorzy
Postów: 6 072
Pomógł: 861
Dołączył: 10.12.2003
Skąd: Dąbrowa Górnicza




Cytat(parzol @ 7.03.2008, 13:54:16 ) *
Nie przewidziałeś drobnej sytuacji kiedy ciąg atrakcji ma postać 1_2_3_9 a ktoś wyszuka według 1_9.

Faktycznie, masz rację - o tym nie pomyślałem :/

Cytat(parzol @ 7.03.2008, 13:54:16 ) *
Wystarczy te '_' usunąć (są zbędne a wręcz niepożądane!) i wyszukiwać tak: LIKE("%1%9%").

No nie do końca. Taki zapis wyszuka Ci zarówna ciąg 1_9 (czyli to o co Ci chodziło) oraz np. 1_19 (co już będzie błędem). Heh, chyba mój pomysł nie jest taki genialny wstydnis.gif
Go to the top of the page
+Quote Post
parzol
post
Post #14





Grupa: Zarejestrowani
Postów: 135
Pomógł: 1
Dołączył: 7.05.2005

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


Cytat(phpion @ 7.03.2008, 13:40:55 ) *
No nie do końca. Taki zapis wyszuka Ci zarówna ciąg 1_9 (czyli to o co Ci chodziło) oraz np. 1_19 (co już będzie błędem).


Hmmm fakt. A jakby zapisywać w bazie dane tak: _1_2_9_ i szukać według: LIKE("%_1_2_%_9_%"). ? Rkingsmiley.png

Cytat(phpion @ 7.03.2008, 13:40:55 ) *
Heh, chyba mój pomysł nie jest taki genialny wstydnis.gif


Nie bądź dla siebie taki surowy smile.gif Jako jedyny dałeś działające rozwiązane na 4 forach!

Ten post edytował parzol 7.03.2008, 15:12:28
Go to the top of the page
+Quote Post

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

 



RSS Aktualny czas: 21.08.2025 - 11:19