Autor Wątek: Zestawienie towarów ze wszystkich magazynów  (Przeczytany 2093 razy)

0 użytkowników i 1 Gość przegląda ten wątek.

Offline kkot92

  • Nowy użytkownik
  • *
  • Wiadomości: 20
  • Reputacja +0/-0
  • Wersja programu: 1.53 (aktualizowana na bieżąco)
Zestawienie towarów ze wszystkich magazynów
« dnia: Październik 25, 2018, 14:47:14 »
Witam serdecznie,

jest to mój pierwszy post na forum więc jeśli zrobię coś nie tak to proszę o wyrozumiałość :) forum przeglądam już od dłuższego czasu, ale do tej pory (kiedy zacząłem bawić się SQL-em) nie było potrzeby wypowiadania się.

Ostatnio odkryłem potencjał drzemiący w zestawieniach SQL i zainspirowało mnie to do nauki tego języka. Mam za sobą kilka prostych zestawień (tak, działają :D), ale problem pojawił się przy próbie napisania czegoś bardziej złożonego - oczywiście dla mnie, bo wiem że dla "wyjadaczy" z forum to pewnie pestka.

Przechodząc do konkretów - chciałem napisać zestawienie, które pokazuje aktualną ilość towarów o stanie niezerowym dla każdego magazynu osobno. Wyszło mi coś takiego

Cytuj
SELECT
tw__Towar.tw_Nazwa AS [Nazwa towaru] FROM tw__Towar,
SUM((tw_Stan.st_Stan) AS [UR] FROM tw_Stan WHERE tw_Stan.st_MagId=1 ),
SUM((tw_Stan.st_Stan) AS [ŁP] FROM tw_Stan WHERE tw_Stan.st_MagId=5 ),
SUM((tw_Stan.st_Stan) AS [KJ] FROM tw_Stan WHERE tw_Stan.st_MagId=6 ),
SUM((tw_Stan.st_Stan) AS [PZ] FROM tw_Stan WHERE tw_Stan.st_MagId=7 ),
SUM((tw_Stan.st_Stan) AS [MS] FROM tw_Stan WHERE tw_Stan.st_MagId=8 ),
SUM((tw_Stan.st_Stan) AS [MJ] FROM tw_Stan WHERE tw_Stan.st_MagId=9 ),
SUM((tw_Stan.st_Stan) AS [NP] FROM tw_Stan WHERE tw_Stan.st_MagId=10 ),
SUM((tw_Stan.st_Stan) AS [ŁĄCZNIE] FROM tw_Stan WHERE tw_Stan.st_MagId IN ('1','5','6','7','8','9','10'))

FROM tw__Towar, tw_Stan WHERE tw_Stan.st_TowId=tw__Towar.tw_Id AND tw_Stan.st_Stan>0

GROUP BY tw__Towar.tw_Nazwa

Jest to ostatnia wersja zapytania, którą próbowałem przerabiać (było już wiele prób przeróbki, jednak żadna właściwa). Co w powyższym zapytaniu napisałem źle? Jeśli daję argumenty dla SUM w nawiasie, to program zwraca mi błąd przy wyrażeniu AS.

Oczywiście powyższe zapytanie utworzyłem na bazie wcześniej napisanego tj.
Cytuj
SELECT
tw__Towar.tw_Nazwa AS [Nazwa towaru],
SUM(tw_Stan.st_Stan) AS [ŁĄCZNIE]

FROM tw__Towar, tw_Stan WHERE tw_Stan.st_MagId IN ('1','5','6','7','8','9','10') AND tw_Stan.st_TowId=tw__Towar.tw_Id AND tw_Stan.st_Stan>0
GROUP BY tw__Towar.tw_Nazwa

Powyższe zapytanie dla jednego magazynu zwraca rekordy, natomiast złożone już nie. Gdzie robię błąd?

Offline tomaszf

  • Zaawansowany użytkownik
  • ****
  • Wiadomości: 523
  • Reputacja +12/-0
  • Wersja programu: Subiekt GT 1.66
Odp: Zestawienie towarów ze wszystkich magazynów
« Odpowiedź #1 dnia: Październik 25, 2018, 14:58:56 »
Nie możesz używać FROM przy każdej kolumnie (nie w ten sposób).
W tym przypadku możesz użyć na przykład CASE WHEN ELSE END:
SELECT
tw__Towar.tw_Nazwa AS [Nazwa towaru] ,
SUM(CASE WHEN tw_Stan.st_MagId = 1 THEN tw_Stan.st_Stan ELSE 0 END) [UR],
SUM(tw_Stan.st_Stan) AS [ŁĄCZNIE]
FROM tw__Towar, tw_Stan WHERE tw_Stan.st_MagId IN (1,5,6,7,8,9,10) AND tw_Stan.st_TowId=tw__Towar.tw_Id AND tw_Stan.st_Stan>0
GROUP BY tw__Towar.tw_Nazwa

W warunku  tw_Stan.st_MagId nie potrzebnie użyłeś apostrofów (kolumna jest typu liczbowego).

Zamiast podawać za każdym razem nazwę tabeli możesz użyć aliasów:

SELECT
tw.tw_Nazwa AS [Nazwa towaru] ,
SUM(CASE WHEN st.st_MagId = 1 THEN st.st_Stan ELSE 0 END) [UR],
SUM(st.st_Stan) AS [ŁĄCZNIE]
FROM tw__Towar tw , tw_Stan st WHERE st.st_MagId IN (1,5,6,7,8,9,10) AND st.st_TowId=tw.tw_Id AND st.st_Stan>0
GROUP BY tw.tw_Nazwa

Offline candy

  • Zaawansowany użytkownik
  • ****
  • Wiadomości: 4876
  • Reputacja +172/-11
Odp: Zestawienie towarów ze wszystkich magazynów
« Odpowiedź #2 dnia: Październik 25, 2018, 15:13:46 »
Co w powyższym zapytaniu napisałem źle?
No... prawie wszystko  ;)
Nie bardzo sie mogłeś zdecydować czy chcesz złączyc tabele i z tego złączenia wybrać dane, czy wyliczyć dane dla każdego towaru bezpośrednio.
Da się na oba sposoby ale nie naraz
NB grupowanie zrobiłeś po nazwie, czyli jak wpiszesz dwa towary o nazwie "Deska", o różnych symbolach to zobaczysz ich mix.

Dwa działające przykłady zrobione na kolanie (reklamacji nie uwzględniam  :P)
SELECT
tw__Towar.tw_Nazwa AS [Nazwa towaru],
Stan1 = SUM((CASE WHEN tw_Stan.st_MagId=1 THEN tw_Stan.st_Stan ELSE 0 END)),
Stan2 = SUM((CASE WHEN tw_Stan.st_MagId=2 THEN tw_Stan.st_Stan ELSE 0 END)),
SUM(tw_Stan.st_Stan) AS [ŁĄCZNIE]
FROM
tw_Stan
INNER JOIN tw__Towar ON tw_Stan.st_TowId=tw__Towar.tw_Id
WHERE
tw_Stan.st_MagId IN ('1','2')
AND tw_Stan.st_Stan>0
GROUP BY tw__Towar.tw_Nazwa

SELECT
Nazwa = T.tw_Nazwa,
Stan1 = (SELECT SUM(st_Stan) FROM tw_Stan WHERE st_MagId = 1 AND st_TowId = T.tw_Id),
Stan2 = (SELECT SUM(st_Stan) FROM tw_Stan WHERE st_MagId = 2 AND st_TowId = T.tw_Id),
[Łącznie] = (SELECT SUM(st_Stan) FROM tw_Stan WHERE st_MagId IN (1,2,3) AND st_TowId = T.tw_Id)
FROM
tw__Towar T
Nie pytaj co rząd może zrobić dla Ciebie. Spytaj czy mógłby tego nie robić.

Offline kkot92

  • Nowy użytkownik
  • *
  • Wiadomości: 20
  • Reputacja +0/-0
  • Wersja programu: 1.53 (aktualizowana na bieżąco)
Odp: Zestawienie towarów ze wszystkich magazynów
« Odpowiedź #3 dnia: Październik 25, 2018, 15:19:43 »
tomaszf,

dziękuję za odpowiedź - oczywiście wszystko zadziałało :) co do w/w rad - nie skracam póki co nazw tabel żeby lepiej zapamiętać ich nazwy, a apostrofy dodałem z przyzwyczajenia (na tzw. wszelki wypadek gdyby było to pole innego typu).

PS. Czy jest jakiś konkretny powód, dlaczego nie można w tym wypadku skorzystać z FROM w taki sposób jak ja to robiłem? Jeśli funkcja jest w nawiasie to powinna teoretycznie obejmować tylko to co jest w jego obrębie, czyli FROM też.

------

Dzięki candy - fajnie to wszystko ująłeś. Jestem dopiero na początku drogi i ten kod jest wynikiem kilkunastu wcześniejszych prób :D także zupełnie się z tym zgadzam :)

Oczywiście sposoby, które przedstawiłeś są trochę inne niż przez tomaszf - dla mnie super, więcej do analizy :)

Offline candy

  • Zaawansowany użytkownik
  • ****
  • Wiadomości: 4876
  • Reputacja +172/-11
Odp: Zestawienie towarów ze wszystkich magazynów
« Odpowiedź #4 dnia: Październik 25, 2018, 15:46:26 »
Czy jest jakiś konkretny powód, dlaczego nie można w tym wypadku skorzystać z FROM w taki sposób jak ja to robiłem? Jeśli funkcja jest w nawiasie to powinna teoretycznie obejmować tylko to co jest w jego obrębie, czyli FROM też.
No jest.
Argumentem dla SUM powinna być nazwa kolumny albo wyrażenie, a Ty napisałeś:SUM((tw_Stan.st_Stan) AS [UR] FROM tw_Stan WHERE tw_Stan.st_MagId=1 )A zatem argumentem dla SUM jest u Ciebie coś takiego:
(tw_Stan.st_Stan) AS [UR] FROM tw_Stan WHERE tw_Stan.st_MagId=1Co to jest? Ani nazwa kolumny, ani poprawne wyrażenie.
No i dlatego nie działa.

Jeśli już to trzeba było napisać
[UR] = (SELECT SUM(st_stan) FROM tw_Stan WHERE tw_Stan.st_MagId = 1)Przy czym to powyższe jest poprawne formalnie, ale niekoniecznie oddaje Twoje intencje  ;)

Nie pytaj co rząd może zrobić dla Ciebie. Spytaj czy mógłby tego nie robić.

Offline dkozlowski

  • Ekspert
  • *****
  • Wiadomości: 17059
  • Reputacja +798/-27
  • Wersja programu: GT/Navireo/nexo
Odp: Zestawienie towarów ze wszystkich magazynów
« Odpowiedź #5 dnia: Październik 25, 2018, 17:29:06 »
Możesz skorzystać z jednego z moich darmowych rozwiązań (Generator zestawienia SQL multistany dla Subiekta GT), aby wygenerować takie zestawienie i zobaczyć jak jest zbudowane.
Daniel, Białystok.

Forum Użytkownikow Subiekt GT

Odp: Zestawienie towarów ze wszystkich magazynów
« Odpowiedź #5 dnia: Październik 25, 2018, 17:29:06 »