Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: JOIN - poprawa zapytania
Forum PHP.pl > Forum > Bazy danych > MySQL
damianooo
Witam,

Potrzebuję do poniższego SELECTa dodać dodatkowe złączenie:
  1. SELECT
  2. t.meet_id,
  3. t.host_type AS hostType,
  4. t.guest_type AS guestType,
  5. u.username AS username,
  6. u.shortname
  7. FROM user u
  8. LEFT JOIN type t ON t.user_id = u.id
  9. WHERE u.STATUS = 1
  10. ORDER BY u.id


Powyższy SELECT zwraca mi 73 rekordy gdzie 3 z nich dzięki złączeniu LEFT JOIN pokazują wartość NULL (co jest równoznaczne z tym że trzech użytkowników nie podało swoich typów) .

Niestety po dodaniu nowego złączenia wyświetla mi tylko 70 rekordów bez tych 3 z NULLem , które bardzo potrzebuję w tym wypadku.

Nowy SELECT:

  1. SELECT
  2. m.matchday_id,
  3. t.meet_id,
  4. t.host_type AS hostType,
  5. t.guest_type AS guestType,
  6. u.username AS username,
  7. u.shortname
  8. FROM user u
  9. LEFT JOIN type t ON t.user_id = u.id
  10. LEFT JOIN meet m ON t.meet_id = m.id
  11. WHERE u.STATUS = 1 AND m.matchday_id = 1
  12. ORDER BY u.id


PS. Tabela User jest połaczona po ID z tabelą TYPE a tabela TYPE jest połączona z tabelę MEET.

Próbowałem z INNER JOIN , RIGHT JOIN i samym JOIN i niestety nie działa sad.gif

zauważyłem że powodem jest to że w klauzuli WHERE dodałem to:
m.matchday_id = 1

to już pewnie zmienia wiele w zapytaniu niestety bo Ci z NULLem odpadają od razu jeśli w tabeli MEET pozycja matchday jest równa 1 .

Ehh pewnie tego nie przeskoczę ...
trueblue
  1. LEFT JOIN meet m ON t.meet_id = m.id AND m.matchday_id = 1
  2. WHERE u.STATUS = 1
damianooo
lepiej ale dalej to nie to

niestety dla matchday = 2 wyświetla mi 73 rekordy z NULL a powinien 0 (zero) ponieważ nikt nie typował w kolejce drugiej , więc nie może tak być.

zmieniłem na INNER JOIN to drugie złączenie ale teraz znowu dostaję 70 rekordów ... ehh ... sad.gif

mam tak :

  1. SELECT
  2. m.matchday_id,
  3. t.meet_id,
  4. t.host_type AS hostType,
  5. t.guest_type AS guestType,
  6. u.username AS username,
  7. u.shortname
  8. FROM user u
  9. LEFT JOIN type t ON t.user_id = u.id
  10. INNER JOIN meet m ON t.meet_id = m.id AND m.matchday_id = 1
  11. WHERE u.STATUS = 1
  12. ORDER BY u.id
emillo91
A sprubój dodać do tego watunek "or" dla kolumny z nullem
trueblue
Zdecyduj się co chcesz osiągnąć.
W przypadku match_day=1 chciałeś mieć 73 rekordy, aby wiedzieć 70 typujących i 3 nietypujących.
Gdy podstawiasz match_day=2 otrzymujesz znów 73 rekordy, w tym 73 nietypujących.
Chcesz mieć 0 dla match_day=2, to złącz poprzez INNER JOIN, ale w tym przypadku otrzymasz 70 dla match_day=1.
damianooo
Sytuacja jest prosta - chcę aby po wybraniu w GUI aplikacji przez użytkownika wybranej kolejki pokazały się wszystkie typy użytkowników. Dodatkowo przy użytkownikach co nie wytypowali ma się pojawić jakiś znak więc muszę wiedzieć którzy to byli.

Wydaje się więc że sprawa prosta ale jak widać nie.

Zastanawiam się czy mam dobrze zaprojektowaną bazę danych. Mam tak:

tabela USER,
tabela TYPE (typ) ; pola m.in.: meet_id
tabela MEET(spotkanie/mecz) ; pola m.in: matchday_id
tabela MATCHDAY (kolejka meczy)

Być może tabelę TYPE też powinienem mieć złączoną z tabelą MATCHDAY i wtedy problem by zniknął ? ,Tylko wydawało mi się że pod względem optymalizacji/normalizacji bazy nie było sensu łączyć skoro z MATCHDAY jest już złączona tabela MEET.

emillo91 , w którym miejscu ten OR ?
trueblue
No to skoro dla match_day=2 otrzymujesz 73 rekordy i wszystkie NULL, to masz dokładnie listę użytkowników, którzy nie wytypowali.
Przecież właśnie chcesz, a przynajmniej powinieneś chcieć taki wynik, bo napisałeś:
Cytat
Dodatkowo przy użytkownikach co nie wytypowali ma się pojawić jakiś znak więc muszę wiedzieć którzy to byli.
damianooo
Problem w tym że na GUI wyświetlane się tylko typy wybranej kolejki - a nie wszystkie.

Próbuję to przerobić dalej w PHP ale kłopot mam w pętli w której łączę listę meczy z listą typów bo za dużo wychodzi mi pól z "-" co oznacza brak typu.
Jak nikt nie wytypował w danej kolejce to chcę aby przy każdym był znak "-" .

  1. foreach($meets as $meet){
  2. foreach ($usersTypes as $types){
  3. if($types['matchday_id'] != NULL){
  4. if($meet['meet_id'] == $types['meet_id']) {
  5. $result[$types['meet_id']]['types'][] = $types['hostType'].' - '.$types['guestType'];
  6. }
  7. }else{
  8. $result[$meet['meet_id']]['types'][] = '-';
  9. }
  10. }
  11. $result[$meet['meet_id']]['meet_id'] = $meet['meet_id'];
  12. $result[$meet['meet_id']]['host'] = $meet['host'];
  13. $result[$meet['meet_id']]['guest'] = $meet['guest'];
  14. }


Obecnie zapytanie mam takie:

  1. SELECT
  2. m.matchday_id,
  3. t.meet_id,
  4. t.host_type AS hostType,
  5. t.guest_type AS guestType,
  6. u.username AS username,
  7. u.shortname
  8. FROM user u
  9. LEFT JOIN type t ON t.user_id = u.id
  10. LEFT JOIN meet m ON t.meet_id = m.id AND m.matchday_id = 2
  11. WHERE u.STATUS = 1
  12. ORDER BY u.id


zwracam mi 73 dla matchday_id = 1 i 73 dla matchday_id = 2


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.