Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: problem z relacja wiele do wielu
Forum PHP.pl > Forum > Bazy danych > MySQL
marceli80
Witam,

mam problem z wybraniem danych z tabel polaczonych relacja wiele do wielu
Jeśli ktoś będzie mógł mi pomoc to poprosze o podpowiedz

Są trzy tabele:

Zapytanie: pokaz nazwiska i imiona osob ktore znaja angielski
podstawowy i rosyjski podstawoawy

Powinien wyswietlic wynik (dwie osoby):
1) Wax Colanko
2) Piotr Kowalski


TABELE:

1) tbl_user
- id_user
- imie_user
- nazwisko_user

2) tbl_jezyki_obce
- id_jezyka
- nazwa_jezyka

3) tbl_jezyki_user (tabela łącząca)
- id_jezyki_users
- id_user
- id_jezyka


Przykładowe dane w tabelach:

tbl_user:
1 - Wax - Colanko
2 - Piotr - Kowalski
3 - Jakub - Wisniewski

tbl_jezyki_obce:
1 - angieslki podstawoawy
2 - angielski sredni
3 - angielski zaawansowany
4 - niemiecki podstawoawy
5 - niemiecki sredni
6 - niemiecki zaawansowany
7 - rosyjski podstawoawy
8 - rosyjski sredni
9 - rosyjski zaawansowany

tbl_jezyki_user:
1 - 1 - 1
2 - 1 - 5
3 - 1 - 7
4 - 2 - 1
5 - 2 - 4
6 - 2 - 7
7 - 3 - 2
8 - 3 - 4
9 - 3 - 7


moje zapytanie ktore nie dziala!!! - co tutaj jest nie tak?

SELECT tbl_user.imie_user, tbl_user.nazwisko_user
FROM
tbl_user, tbl_jezyki_obce, tbl_jezyki_user
WHERE
tbl_jezyki_user.id_user = tbl_user.id_user
AND
tbl_jezyki_user.id_jezyka = tbl_jezyki_obce.id_jezyka
AND (tbl_jezyki_user.id_jezyka = '1' AND tbl_jezyki_user.id_jezyka = '7')



id_jezyka = '1' -> angielski podstawoawy
id_jezyka = '7' -> rosyjski podstawoawy

oczekiwany wynik:
1) Wax Colanko
2) Piotr Kowalski

tylko te dwie osoby znaja oba jezyki angielski podstawoawy i rosyjski podstawoawy

Dzieki i pozdrawaim,
Marcel
maryaan
Cytat(marceli80 @ 14.02.2007, 00:05:01 ) *
mam problem z wybraniem danych z tabel polaczonych relacja wiele do wielu
to znaczy jaki problem? bo na razie tylko opisales co masz a nie napisales czego nie umiesz zrobic?
Cytat
moje zapytanie ktore nie dziala!!! - co tutaj jest nie tak?
nie dziala to znaczy co? wywala bledy czy co?

co w "tlumaczeniu na polski" robi ten warunek:
  1. (tbl_jezyki_user.id_jezyka = '1' AND tbl_jezyki_user.id_jezyka = '7')
?
marceli80
chodzi o to aby pokazal osoby ktore znaja dwa jezyki: angielski
podstawowy i rosyjski podstawoawy

zapytanie ktore przedstawilem nie wyswielta oczekiwanego wyniku
tzn:
dla mnie wynikiem sa osoby:
1) Wax Colanko
2) Piotr Kowalski

tylko te dwie osoby znaja oba jezyki angielski podstawoawy i rosyjski podstawoawy

trzecia osoba z przykaldu Jakub Wisniewski zna rosyjski podstawoawy ale nie zna angielskiego podstawowego wiec nie powinien sie wyswietlic


(tbl_jezyki_user.id_jezyka = '1' AND tbl_jezyki_user.id_jezyka = '7')
- uznalem ze to jest wrunek aby wybrac angielski podstawoawy i rosyjski podstawoawy
tzn:

id_jezyka = '1' -> angielski podstawoawy
id_jezyka = '7' -> rosyjski podstawoawy

Widocznie zle rozumiem te relacje i nie potrafie ulozyc odpowiedniego zapytanie dlatego prosze o pomoc.
W skrocie moje pytanie brzmi:

Prosze napisac zapytanie ktore na podstawie przedstawionych tabel i wartosci wyswietli tylko te osoby ktore znaja oba jezyki. (angielski podstawoawy i rosyjski podstawoawy)


Pozdr,
Marcel
Kosmi
Moja propozycja:

  1. SELECT imie_user, nazwisko_user FROM tbl_user AS u JOIN tbl_jezyki_user AS j_u ON (u.id_user=j_u.id_user AND j_u.id_jezyka=1) JOIN tbl_jezyki_user AS j_u2 ON (u.id_user=j_u2.id_user AND j_u2.id_jezyka=7)


Lub też jeżeli jest SQL z obsługą podzapytań:

  1. SELECT imie_user, nazwisko_user FROM tbl_user AS u JOIN tbl_jezyki_user AS j_u ON (u.id_user=j_u.id_user AND j_u.id_jezyka=(SELECT id_jezyka FROM tbl_jezyki_obce WHERE nazwa_jezyka='angieslki podstawoawy')) JOIN tbl_jezyki_user AS j_u2 ON (u.id_user=j_u2.id_user AND j_u2.id_jezyka=(SELECT id_jezyka FROM tbl_jezyki_obce WHERE nazwa_jezyka='rosyjski podstawoawy'))


Pozdrawiam
Kosmi
maryaan
Cytat(marceli80 @ 14.02.2007, 11:20:19 ) *
(tbl_jezyki_user.id_jezyka = '1' AND tbl_jezyki_user.id_jezyka = '7')
- uznalem ze to jest wrunek aby wybrac angielski podstawoawy i rosyjski podstawoawy
troche przekombinowales bo pole nie moze miec dwoch roznych wartosci jednoczesnie, masz blad logiczny w tym wlasnie fragmencie zapytania
Namrasit
Witam!

Odświeżam temat, bowiem napotkałem na podobny problem jak marceli80. Z tego, co mi do tej pory poradzono to powinienem zamienić relację wiele do wielu na jeden do wielu. Nie wiem jednak jak to zrobić i czy to w ogóle sprawdzi się w tym przypadku. Jeśli ktoś miał podobny problem, to bardzo proszę o jakieś wskazówki.

Z góry dziękuję i pozdrawiam smile.gif .
Dawid.
erix
A podstawy baz danych zna?
Namrasit
Zna, zna biggrin.gif . Poradzono mi zapoznać się z normalizacją bazy danych. Nie wiem jednak czy to zagadnienie coś pomoże.
Przedstawię może pokrótce mój przykład:

Tabela users_cars:



Jest to tabela pomocnicza przy relacji wiele do wielu. Chcę w jednym zapytaniu uzyskać ID użytkownika, który posiada określone samochody. Dla przykładu
mając dane ID samochodów 1, 2 i 3, powinienem jako wynik uzyskać 2. Zapytanie typu:

"SELECT userID FROM users_cars WHERE carID IN (1, 2, 3)"

nie działa tak jak chcę, bowiem zwraca użytkowników, którzy posiadają samochody 1 lub 2 lub 3. Wgłębiam się powoli w temat normalizacji bazy danych,
jednak jak na razie nie widzę nic nowego co mogłoby mi się przydać.

Pozdrawiam,
Dawid
erix
No skoro podałeś nazwę nie tej kolumny, co trzeba, to się dziwisz...? PS. zdałoby się distinct.
Namrasit
To była tylko literówka tongue.gif . Jeśli chodzi o DISTINCT to chyba za wiele tu nie pomoże. Polecenie to usuwa identyczne wiersze zwrócone w zapytaniu, w przy tym problemie nie o to chodzi.

Może napisze tak:

Mając taki układ tabel



Widzimy, że jedna osoba może jeździć kilkoma samochodami, a każdym samochodem może jeździć wiele osób (przykład wyssany z palca tongue.gif ). Naszym zadaniem jest znalezienie osoby, która jeździ tylko przykładowo trzema podanymi samochodami (carID: 1, 2 i 3). Jak to zrobić? Wszelkie zapytania, które próbowałem formułować, powodują wyświetlenie użytkowników jeżdżących samochodem 1 lub 2 lub 3.

Dziękuję za wszelkie sugestie i jeszcze raz pozdrawiam,
Dawid.
erix
Aha, masz na myśli osoba, która jeździ 1 I 2 I 3, a nie 1 LUB 2 LUB 3?
Namrasit
Dokładnie tak smile.gif. Chodzi o 1 i 2 i 3 jednocześnie.
erix
  1. WHERE warunek AND warunek AND warunek...

Pomyśl, co dalej.
Namrasit
Taki warunek raczej nie przejdzie. Zapytanie typu:

  1. SELECT userID FROM users_cars WHERE carID = 1 AND carID = 2 AND carID = 3


jest logicznie niemożliwe, zresztą tego typu złożenie były już poruszane w tym temacie smile.gif

Dawid.
erix
Ałć, faktycznie.

Klepię z palucha:
  1. SELECT userID FROM users_cars GROUP BY userID HAVING carID=1 AND carID=2 AND carID=3
Namrasit
W tym przypadku jest tak samo jak w poprzednim, wartości carID nie mogą być równocześnie równe 1, 2 i 3 smile.gif

Dawid.
erix
  1. SELECT * , count( car ) AS carsCount
  2. FROM `users2cars` WHERE car =1 OR car =2 OR car =3
  3. GROUP BY user
  4. HAVING carsCount =3

Fajny problem. [;
Namrasit
Powiem Ci, że problem bardzo ciekawy. Zwykle nie udzielam się na forach, bo wszystko znajduję w sieci, ale w tym przypadku jest inaczej smile.gif.

Wracając do tematu, to Twoje zapytanie po wstępnych testach wydaje się działać prawidłowo biggrin.gif . Pozwoliłem sobie je tylko troszkę przerobić:

  1. SELECT userID FROM users_cars WHERE carID = 1 OR carID = 2 OR carID = 3
  2. GROUP BY userID
  3. HAVING count(carID) = 3


W ten sposób w wyniku otrzymujemy tylko użytkownika który spełnia tylko i wyłącznie te 3 kryteria. Takie niby OR ale AND tongue.gif. Będę to testował na większej aplikacji i zobaczę jak się sprawuje. Wstępnie masz piwko u mnie smile.gif.

Pozdrawiam
Dawid.
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-2019 Invision Power Services, Inc.