Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

 
Reply to this topicStart new topic
> IF ELSE i IF NOT EXIST Statement
adek-
post 28.03.2017, 12:47:55
Post #1





Grupa: Zarejestrowani
Postów: 124
Pomógł: 2
Dołączył: 19.04.2007
Skąd: Częstochowa

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


Cześć chłopaki, może któryś miałby chwilę wyklarować mi pewną rzecz związaną z klauzulą NOT EXISTS i IF ELSE w MySQL, bo wujek google nie odnalazł mi jakichś dobrych konkretnych tutoriali, albo sposobów użycia w takim przypadku jaki ja posiadam. Ogólnie przez mój poniżej opisany problem zakupiłem sobie dzisiaj na allegro książkę o SQL z czego niezmiernie się cieszę, bo nie sądziłem, że internet będzie niewystarczający... Czekam na nią z niecierpliwością!

Zasada działania:
Mam proste zapytanie, gdzie do tabeli z transakcjami (transaction_table AS tt, dodawanymi przez pracowników) doklejam LEFT JOINEM tabelę z danymi wyeksportowanymi z programu kasowego (table_import AS ti). Na koniec każdego dnia jest eksport z programu i import do bazy danych, gdzie są dane o zysku do każdej transakcji, obie tabele łącze numerem 'mtn', który jest nadawany przez program kasowy do każdej transakcji (widoczny w tabeli ti), ten numer przepisuje również pracownik , gdy na bieżąco dodaje tr. do bazy do tabeli z transakcjami (tt) - program kasowy pokazuje mu ten numer przed zatwierdzeniem transakcji. I wszystko jak narazie działa...
Problem:
Problem jest taki, że, gdy w danym dniu nie zaimportuję danych z programu kasowego (ti), to przy tym zapytaniu nawet nie wyświetlą mi się dzisiejsze transakcje które są jeszcze bez zaimportowanego zysku dodane przez pracownika w tabeli (tt). Wszystkie funkcje SUM() z tabeli ti w tych dniach z oczywistego powodu wywalają błąd (bo danych do wyliczeń tam jeszcze nie ma) smile.gif

Działające zapytanie:
  1. SELECT tt.id_placowki, data_transakcji, rodzaj_transakcji, STATUS, zysk,
  2. COUNT(data_transakcji) AS suma_tt_w_mc,
  3. SUM(IF(ti.Direction = 'I', -1 * ti.ClearCharges, 0)) AS zysk_inbound_imported,
  4. SUM(IF(ti.Direction = 'O', ti.TotalCharges - ti.ClearCharges, 0)) AS zysk_outbound_imported,
  5. SUM(IF(ti.Direction = 'I', -1 * ti.ClearCharges, 0) + IF(ti.Direction = 'O', ti.TotalCharges - ti.ClearCharges, 0)) AS zysk_sum,
  6. FROM transaction_table AS tt
  7. LEFT JOIN point_of_sell AS pos ON pos.id_placowki = tt.id_placowki
  8. LEFT OUTER JOIN table_import AS ti ON ti.MTN = tt.mtn
  9. WHERE YEAR(data_transakcji) = '$rok' AND MONTH(data_transakcji) = '$miesiac'
  10. AND tt.id_placowki = '$placowka'
  11. AND ti.PayDate <> '0000-00-00'
  12. AND (ti.PayDate = tt.data_transakcji OR ti.RecDate = tt.data_transakcji)
  13. GROUP BY data_transakcji
  14. ORDER BY data_transakcji ASC


Moje pytania:
1. Czy nie jest tak, że jak dam do t1 LEFT OUTER JOIN t2, to powinien mi i pokazać wszystkie dane z z t1 (tutaj transaction_table), a w pola pobierane z t2 (tutaj table_import), gdzie nic niema - powinien dokleić NULL?
2. Jeśli 1 jest na nie, to jak spreparować zapytanie, aby wyświetlało mi zerowe dane, z aktualnego dnia, gdy tabela importu jeszcze nie ma powiązanych rekordów z transakcjami w tt? Zapewne tutaj chyba trzeba użyć jakiegoś większego IF NOT EXIST i IF ELSE, co próbowałem bezskutecznie, bo nigdy nie miałem potrzeby ich używania.

Tak więc próbowałem zabrać się do tego od strony zapytania WHERE NOT EXIST w imię zasady "SELECT * FROM tabela t1 WHERE NOT EXISTS (SELECT 1 FROM druga_tabela t2 WHERE t1.id = t2.id)"

Końcówka zapytania od WHERE:
  1. WHERE NOT EXISTS (SELECT * FROM transaction_table WHERE YEAR(data_transakcji) = '$rok' AND MONTH(data_transakcji) = '$miesiac' AND id_placowki = '$placowka')
  2. AND YEAR(data_transakcji) = '$rok' AND MONTH(data_transakcji) = '$miesiac'
  3. AND tt.id_placowki = '$placowka'
  4. AND ti.PayDate <> '0000-00-00'
  5. AND (ti.PayDate = tt.data_transakcji OR ti.RecDate = tt.data_transakcji)
  6. GROUP BY data_transakcji
  7. ORDER BY data_transakcji ASC


jak i też od strony warunków IF przy SELECT

  1. SELECT tt.id_placowki, data_transakcji, rodzaj_transakcji, STATUS, zysk,
  2. COUNT(data_transakcji) AS suma_tt_w_mc,
  3. IF EXISTS ti.Direction AND ti.Direction = 'I' THEN
  4. SUM(-1 * evi.ClearChargesLOC) AS zysk_inbound_imported
  5. ELSE IF EXISTS ti.Direction AND ti.Direction = 'O' THEN
  6. SUM(ti.TotalCharges - ti.ClearCharges) AS zysk_outbound_imported
  7. ELSE IF NOT EXISTS evi.Direction THEN
  8. ti.ClearCharges = 0 AND ti.TotalCharges = 0
  9. END IF
  10. FROM transaction_table AS tt
  11. LEFT JOIN point_of_sell AS pos ON pos.id_placowki = tt.id_placowki
  12. LEFT OUTER JOIN table_import AS ti ON ti.MTN = tt.mtn
  13. WHERE YEAR(data_transakcji) = '$rok' AND MONTH(data_transakcji) = '$miesiac'
  14. AND tt.id_placowki = '$placowka'
  15. AND ti.PayDate <> '0000-00-00'
  16. AND (ti.PayDate = tt.data_transakcji OR ti.RecDate = tt.data_transakcji)
  17. GROUP BY data_transakcji
  18. ORDER BY data_transakcji ASC


Naprowadźcie mnie, w którym najbardziej optymalnym kierunku szukać informacji jak przyjdzie mi ta książka? Domyślam się, że jeszcze źle kombinuje z poprawnością zapytania, ale założenie teoretyczne idzie w dobrym kierunku?
Go to the top of the page
+Quote Post
mmmmmmm
post 28.03.2017, 20:06:46
Post #2





Grupa: Zarejestrowani
Postów: 1 421
Pomógł: 310
Dołączył: 18.04.2012

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


MySQL nie jest dla ciebie dobrą bazą na początek. Zdecydowanie źle grupujesz. A ten IF w połączeniu z SUM, to... chyba tylko zadziała na MySQL. Co gorsza, pewnie nikt nie wie jak...
Jeśli zaczynasz przygodę z bazami, to zacznij od postgreSQL-a lub SQLite, Są bardziej zgodne ze standardem.
Go to the top of the page
+Quote Post
adek-
post 30.03.2017, 22:04:45
Post #3





Grupa: Zarejestrowani
Postów: 124
Pomógł: 2
Dołączył: 19.04.2007
Skąd: Częstochowa

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


mmmmmmm być może, ale działa i nie jestem pierwszym, który używa funkcji IF() w klauzuli SUM. Po prostu zsumuje wszystko, co funkcja zwróci i tyle, w końcu to nie warunek, a dedykowana funkcja od MySQL'a wink.gif

Nie jest też tak, że jestem zielony. Po prostu nie używałem zaawansowanych funkcji MySQL'a do obrabiania danych, a raczej wszystkie operacje robiłem w PHP. Minus? A no taki, że właśnie jak chcę większość rzeczy zrobić w zapytaniu, to się okazuje, że są problemy wybrakowanej wiedzy, czy umiejętności tworzenia zaawansowanych zapytań.

Książka dotarła i poradziłem sobie z wszystkimi rzeczami... okazuje się, że nie musiałem nawet robić warunków IF ELSE, których notabene i tak nie było w książce i w ogóle mało jest tego na forach, więc w pierwszej chwili podupadłem na umyśle, ale w ostateczności okazało się, że tak jak mówisz - źle grupowałem! wink.gif

  1. FROM transaction_table AS tt
  2. LEFT JOIN point_of_sell AS pos ON pos.id_placowki = tt.id_placowki
  3. LEFT OUTER JOIN table_import AS ti ON ti.MTN = tt.mtn AND PayDate <> '0000-00-00' AND TxnStatus = 'S' AND (ti.PayDate = tt.data_transakcji OR ti.RecDate = tt.data_transakcji)
  4. WHERE YEAR(data_transakcji) = '$rok' AND MONTH(data_transakcji) = '$miesiac'


Małe przestawienie załatwiło sprawę.
Podpowiedź nie była nijak pomocna, ale była trafna (grupowanie), dlatego daję soga!
Dziękuję za zainteresowanie smile.gif

Ten post edytował adek- 31.03.2017, 06:16:02
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 Wersja Lo-Fi Aktualny czas: 27.04.2024 - 03:34