Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: Łączenie dwóch tabel trzecią.
Forum PHP.pl > Forum > Bazy danych > MySQL
Dexiu
Mam dwie tabele połączone trzecią (połączenie n:m).

Tablica: localization; Kolumny: localizationID [PK], localizationIP, localizationName, localizationComment

Tablica: products; Kolumny: productsID [PK], productsName, productsVersion, productsType

Tablica łącząca: localizationProducts; Kolumny: localizationID [PK], [i]productsID [PK]

Tablica products zawiera produkty pogrupowane na 3 typy (productsType).
Wyciągam dane localizationIP, productsName
i teraz pytanie jak wyciągnąć powyższe dane z mała zmianą.
Zamiast productsName chciałbym wyciągnąć trzy kolumny dla poszczególnych productsType.
Aktualnie mam zapytanie:
  1. SELECT l.localizationIP AS IP, IF (p.productsType='Produkt 1', p.productsName, '') AS 'Produkt 1',
  2. IF (p.productsType='Produkt 2', p.productsName, '') AS 'Produkt 2',
  3. IF (p.productsType='Produkt 3', p.productsName, '') AS 'Produkt 3'
  4. FROM localization l
  5. LEFT JOIN localizationproducts lp ON lp.localizationID=l.localizationID
  6. LEFT JOIN products p ON lp.productsID=p.productsID
  7. WHERE l.localizationID=1
  8. GROUP BY l.localizationID, p.productsType;

co daje wynik:
Kod
IP          Produkt1  Produkt2  Produkt3
10.8.3.9                        Nazwa3    
10.8.3.9              Nazwa2        
10.8.3.9    Nazwa1

Jak usunę p.productsType z GROUP BY
mam wynik:
Kod
IP          Produkt1  Produkt2  Produkt3
10.8.3.9    Nazwa1

Efekt jaki chciałbym osiągnąć to:
Kod
IP          Produkt1  Produkt2  Produkt3
10.8.3.9    Nazwa1    Nazwa2    Nazwa3


POMOCY!!! sadsmiley02.gif
kefirek
Daj może tak
  1. GROUP BY IP
Dexiu
Nic nie daje.

A doszedł jeszcze jeden problem, a mianowicie jeśli dwa lub więcej produktów ma jakiś jeden typ to wypisuje tylko jeden produkt.
Próbowałem dodać group_concat w if'ach ale robi mi wtedy wszystkie produkty w kolumnie.

Zapytanie:
  1. SELECT l.localizationIP AS IP, IF (p.productsType='Produkt 1', group_concat(p.productsName), '') AS 'Produkt 1',
  2. IF (p.productsType='Produkt 2', group_concat(p.productsName), '') AS 'Produkt 2',
  3. IF (p.productsType='Produkt 3', group_concat(p.productsName), '') AS 'Produkt 3'
  4. FROM localization l
  5. LEFT JOIN localizationproducts lp ON lp.localizationID=l.localizationID
  6. LEFT JOIN products p ON lp.productsID=p.productsID
  7. WHERE l.localizationID=1
  8. GROUP BY l.localizationID;

Wynik
Kod
IP          Produkt1                   Produkt2  Produkt3
10.8.3.9    Nazwa1,Nazwa2,Nazwa3,Nazwa4

Jak dodam w group by p.productsType to mam:
Kod
IP          Produkt1  Produkt2  Produkt3
10.8.3.9                        Nazwa3 ,Nazwa4  
10.8.3.9              Nazwa2        
10.8.3.9    Nazwa1
mongea
hi

wynikiem polaczenia jest iloczyn kartezjanski, dostajesz wiec zbior wynikowych wierszy
ty probujesz na sile te wiersze strescic do jednego wiersza - musisz wiec zadac takie zapytanie ktore w wyniku da jedna krotke - da sie to zrobic rozbudowujac (i przy okazji gmatwajac zapytanie)
ale czy nie lepiej sposob prezentacji pozostawic juz php ?

kolejna rzecz: jak chcesz miec prezentowane wyniki gdy dla danej lokalizacji bedzie np. 50 produktow typu Produkt 3, a z pozostalych typow nie bedzie zadnego produktu ?
Dexiu
Cytat(mongea @ 4.03.2009, 12:07:38 ) *
wynikiem polaczenia jest iloczyn kartezjanski, dostajesz wiec zbior wynikowych wierszy

Oki, to jest dla mnie jasne.

Cytat(mongea @ 4.03.2009, 12:07:38 ) *
ty probujesz na sile te wiersze strescic do jednego wiersza - musisz wiec zadac takie zapytanie ktore w wyniku da jedna krotke - da sie to zrobic rozbudowujac (i przy okazji gmatwajac zapytanie)

Świetnie i tu pytanie "Jak to zrobić??"

Cytat(mongea @ 4.03.2009, 12:07:38 ) *
ale czy nie lepiej sposob prezentacji pozostawic juz php ?

Nie, nie lepiej gdyż przesłanie danych w powiedzmy 5 razy większej ilości wierszy wogóle mnie nie urządza. To co tu opisuję to tylko kilka kolumn z kilkudziesięciu które będę przesyłał (baza jest w innym miejscu niż interpreter php). I stąd próba odpytania serwera MySQL o jak najmniejszą liczbę danych. Wysłanie kilka do kilkunastu razy większej ilości danych odpada.

Cytat(mongea @ 4.03.2009, 12:07:38 ) *
kolejna rzecz: jak chcesz miec prezentowane wyniki gdy dla danej lokalizacji bedzie np. 50 produktow typu Produkt 3, a z pozostalych typow nie bedzie zadnego produktu ?

Nie ma możliwości aby było dużo produktów (tablica zawiera dużo rekordów które służą do wpisywania 5 grup produktów zawierających po kilka produktów w kilkuset wersjach - nie ma możliwości aby było więcej niż kilka produktów w kolumnie - nie może występować w jednej lokalizacji produkt w kilku wersjach) natomiast kolumny w których nic nie ma, powinny wyświetlać puste.
mongea
Cytat(Dexiu @ 4.03.2009, 12:50:08 ) *
Nie ma możliwości aby było dużo produktów (tablica zawiera dużo rekordów które służą do wpisywania 5 grup produktów zawierających po kilka produktów w kilkuset wersjach - nie ma możliwości aby było więcej niż kilka produktów w kolumnie - nie może występować w jednej lokalizacji produkt w kilku wersjach) natomiast kolumny w których nic nie ma, powinny wyświetlać puste.


konkretnie:
w danej lokalizacji masz: 2 produkty o typie Produkt1, 0 produktow o typie Produkt2, 3 produkty o typie Produkt3

jaka chcesz miec wynik (poprosze wierszami)
Dexiu
Kod
IP         | Produkt1  | Produkt2 | Produkt3       |
----------------------------------------------------
10.8.3.9   | NP11,NP12 |          | NP31,NP32,NP33 |
mongea
Cytat(Dexiu @ 4.03.2009, 14:13:43 ) *
Kod
IP         | Produkt1  | Produkt2 | Produkt3       |
----------------------------------------------------
10.8.3.9   | NP11,NP12 |          | NP31,NP32,NP33 |


zmienia to troche postac rzeczy i nadal uwazam ze da sie to znacznie optymalniej rozwiazac, ale jezeli jestes uparty winksmiley.jpg do tej postaci to powinno pomoc:
Kod
SELECT l.localizationIP,
GROUP_CONCAT(DISTINCT p1.productsName) AS "Produkt 1",
GROUP_CONCAT(DISTINCT p2.productsName) AS "Produkt 2",
GROUP_CONCAT(DISTINCT p3.productsName) AS "Produkt 3"
FROM localization l
LEFT JOIN products p1 ON p1.productsType = "Produkt1" AND EXISTS (SELECT * FROM localizationproducts lp WHERE lp.localizationID = l.localizationID AND lp.productsID = p1.productsID)
LEFT JOIN products p2 ON p2.productsType = "Produkt2" AND EXISTS (SELECT * FROM localizationproducts lp WHERE lp.localizationID = l.localizationID AND lp.productsID = p2.productsID)
LEFT JOIN products p3 ON p3.productsType = "Produkt3" AND EXISTS (SELECT * FROM localizationproducts lp WHERE lp.localizationID = l.localizationID AND lp.productsID = p3.productsID)
WHERE
l.localizationID = 1
GROUP BY l.localizationID
Dexiu
Ok dzięki działa.
Pozdrawiam.
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.