Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

> [IF][CASE]![JOIN] Złączenie z kilku tabel z warunkami
vokiel
post
Post #1





Grupa: Zarejestrowani
Postów: 2 592
Pomógł: 445
Dołączył: 12.03.2007

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


Witam. Mam problem ze złączeniem danych z kilku tabel, w zależności od wartości danych w jednej kolumnie.
Dokładniej:
mam 3 tabele:
PRODUCTS
| ID | NAME | .... |

AWARDS
| ID | NAME |...|

OPERATIONS
| ID | .... | ACTION | PRODUCT |

I teraz pojawia się problem bo mamy ogólnie 3 dostępne akcje:
1 - standard
2 - produkt
3 - nagroda

czyli przykładowe rekordy będą wyglądać tak:
OPERATIONS
| 1 | ... | 1 | NULL |
| 2 | ... | 2 | 2 |
| 3 | ... | 3 | 1 |
| 4 | ... | 2 | 1 |
| 5 | ... | 1 | NULL |

W wyniku chciałbym otrzymać:
QUERY
| 1 | ... | 1 | NULL |
| 2 | ... | 2 | AWARD 2 NAME |
| 3 | ... | 3 | PRODUCT 1 NAME |
| 4 | ... | 2 | AWARD 1 NAME |
| 5 | ... | 1 | NULL |

Zatem JOIN chyba odpada, bo nie będzie wiedział z której tabeli dołączać.
Przydałby się IF a może bardziej CASE

skleciłem coś takiego z case, ale nie działa tak jak trzeba, w kolumnie NAME dostaje wszędzie NULL:
  1. SELECT
  2. `OPERATIONS`.`ID` ,
  3. `OPERATIONS`.`ACTION` ,
  4. CASE
  5. WHEN `OPERATIONS`.`ACTION` =2 THEN `AWARDS`.`NAME`
  6. WHEN `OPERATIONS`.`ACTION` =3 THEN `PRODUCTS`.`NAME`
  7. END AS `NAME` ,
  8. FROM `OPERATIONS` LEFT OUTER JOIN `AWARDS` ON `OPERATIONS`.`PRODUCT` = `AWARDS`.`ID`
  9. LEFT OUTER JOIN `PRODUCTS` ON `OPERATIONS`.`PRODUCT` = `PRODUCTS`.`ID`
  10.  
  11. WHERE `OPERATIONS`.`ID` >10 LIMIT 0, 30


A może najlepszym rozwiązaniem byłoby dodanie kolumn dla AWARDS i PRODUCTS?

Ten post edytował vokiel 23.07.2008, 13:07:06
Go to the top of the page
+Quote Post
 
Start new topic
Odpowiedzi
vokiel
post
Post #2





Grupa: Zarejestrowani
Postów: 2 592
Pomógł: 445
Dołączył: 12.03.2007

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


Działające poprawnie zapytanie (bez uproszczeń):
  1. SELECT `PROG_POINTS`.`ID` , `PROG_POINTS`.`CODE` , CONCAT( `PROG_USR`.`IMIE` , ' ', `PROG_USR`.`NAZWISKO` ) AS `USR` , `PROG_POINTS`.`POINTS` , `PROG_POINTS`.`ACTION` , `PROG_POINTS`.`DATE_TIME` , CONCAT( `PROG_USR_JB`.`NAME` , ' ', `PROG_USR_JB`.`SURNAME` ) AS `USR_JB` ,
  2. CASE
  3. WHEN `PROG_POINTS`.`ACTION` =3
  4. THEN `PROG_AWARD_LIST`.`AWARD_NAME`
  5. WHEN `PROG_POINTS`.`ACTION` =2
  6. THEN `PROG_PRODUCTS`.`NAME`
  7. END AS `AWARD_NAME`
  8. FROM `PROG_USR` , `PROG_POINTS`
  9. LEFT JOIN `PROG_AWARD_LIST` ON ( `PROG_POINTS`.`ACTION` =3 AND `PROG_POINTS`.`PRODUCT_ID` = `PROG_AWARD_LIST`.`ID` )
  10. LEFT JOIN `PROG_PRODUCTS` ON ( `PROG_POINTS`.`ACTION` =2 AND `PROG_POINTS`.`PRODUCT_ID` = `PROG_PRODUCTS`.`ID` )
  11. LEFT OUTER JOIN `PROG_USR_JB` ON `PROG_POINTS`.`PASSED_BY` = `PROG_USR_JB`.`ID`
  12. WHERE `PROG_POINTS`.`USR_ID` = `PROG_USR`.`ID`
  13. ORDER BY `PROG_POINTS`.`DATE_TIME` DESC LIMIT 0, 100


Musi być CASE zamiast IF, bo IF(awards.id IS NULL, products.name, award.name) skutkuje, że wyświetla zawsze, tylko products.name, zmieniłem na początku na IS NOT NULL, żeby wyświetlał, jak pole nie będzie puste (ale wtedy niezależnie od parametru ACTION wyświetlał własnie tylko "products.name". Zatem skorzystałem z CASE, który okazał się tu idealnym rozwiązaniem.

@ddiceman bardzo pomocny okazał się Twój LEFT JOIN:
  1. LEFT JOIN products ON operations.action = 2 AND operations.product = product.id

Dzięki (IMG:http://forum.php.pl/style_emoticons/default/smile.gif)
Go to the top of the page
+Quote Post

Posty w temacie


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: 30.12.2025 - 03:23