Autor Wątek: zapytania SQL - produkty na ktorych nie bylo żadnego ruchu od jakiegoś czasu  (Przeczytany 8946 razy)

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

Offline gimlak

  • Nowy użytkownik
  • *
  • Wiadomości: 1
  • Reputacja +0/-0
  • Wersja programu: 1.66
Ktoś pomoże jak wyfiltrować przez własne zapytania SQL produkty na których nie było żadnych ruchów od np 6 lat (i stan magazynowy jest 0). mam dużo produktów na subiekci które chciałbym wyfiltrować jako nieaktywne..

Offline yemet

  • Zaawansowany użytkownik
  • ****
  • Wiadomości: 1271
  • Reputacja +46/-1
  • Wersja programu: Navireo
Dla ruchu dok_pozycja i/lub dok_magruch, dla stanów tw_stan lub przechwycone profilerem fabryczne zestawienie remanentowe.

Warto spojrzeć też na fabryczne zestawienie pt. towary niechodliwe.

Offline MacKar

  • Nowy użytkownik
  • *
  • Wiadomości: 3
  • Reputacja +0/-0
  • Wersja programu: 1.7
select tw_Symbol Symbol, tw_Nazwa Nazwa, convert(varchar(10),max(dok_DoDokDataWyst),120) [Data] from tw__Towar
join dok_Pozycja on ob_TowId = tw_Id
join dok__Dokument on dok_Id = ob_DokMagId
join tw_stan on st_TowId = tw_Id
where isnull(st_Stan, 0) = 0
and DATEDIFF(year,dok_DoDokDataWyst,getdate()) >= {I: Nieużywano przez lat: 0}
group by tw_Nazwa, tw_Symbol
order by max(dok_DoDokDataWyst) desc

Offline candy

  • Zaawansowany użytkownik
  • ****
  • Wiadomości: 4913
  • Reputacja +173/-11
select tw_Symbol Symbol, tw_Nazwa Nazwa, convert(varchar(10),max(dok_DoDokDataWyst),120) [Data] from tw__Towar
join dok_Pozycja on ob_TowId = tw_Id
join dok__Dokument on dok_Id = ob_DokMagId
join tw_stan on st_TowId = tw_Id
where isnull(st_Stan, 0) = 0
and DATEDIFF(year,dok_DoDokDataWyst,getdate()) >= {I: Nieużywano przez lat: 0}
group by tw_Nazwa, tw_Symbol
order by max(dok_DoDokDataWyst) desc
Nie bardzo wiem jaka jest idea tego SELECTa ale nie wydaje mi się żeby pokazywał to co trzeba.
1. Skąd tam i co ma robić dok_DoDokDataWyst? Przecież dla znacznej części dokumentów tam będzie NULL
2. Co ma robić warunek isnull(st_Stan, 0) = 0 ? Jeśli towar leży od 5 lat na magazynie to stan ma niezerowy, a ruchu nie ma żadnego
3. W tabeli stanów ten sam towar występuje tyle razy ile jest magazynów, więc też czegoś tu brakuje.
Nie pytaj co rząd może zrobić dla Ciebie. Spytaj czy mógłby tego nie robić.

Offline birds22

  • Ekspert
  • *****
  • Wiadomości: 9228
  • Reputacja +1306/-21
  • Wersja programu: Najnowsza
Masz rację @candy - tutaj wiele brakuje. To moja wina, bo tylko rzuciłem na to okiem (a że już wzrok nie taki...) :)
Zapytanie zrobił bardzo młody chłopak, który jeszcze kilka dni temu niewiele wiedział co to jest baza danych i jak wyglądają zapytania SQL, nie miał też pojęcia co to jest Subiekt, ale w ramach praktyk szkolnych chce się uczyć i ja to doceniam:)
Chłopak ma jednak potencjał, więc nie będę za niego tego poprawiał, ale obiecuję, że  w poniedziałek poprawi się i napisze poprawne zapytanie :)
Sławek, Zduńska Wola

Offline candy

  • Zaawansowany użytkownik
  • ****
  • Wiadomości: 4913
  • Reputacja +173/-11
Nie masz się co tłumaczyć, pieniędzy za to nie wziął, więc reklamacji nie będzie.
Po prostu cos tam zwróciło moja uwagę, spojrzałem jeszcze raz i pomyślałem że lepiej niech nikt na tym nie bazuje.
Nie pytaj co rząd może zrobić dla Ciebie. Spytaj czy mógłby tego nie robić.

Offline MacKar

  • Nowy użytkownik
  • *
  • Wiadomości: 3
  • Reputacja +0/-0
  • Wersja programu: 1.7
select tw_Symbol Symbol, tw_Nazwa Nazwa, Stan.Stan from tw__Towar t
join(
select st_TowId, sum(st_Stan) Stan from tw_Stan
group by st_TowId
) stan
on stan.st_Towid = tw_Id
left join
(
select ob_towid from dok_Pozycja
join dok__Dokument on dok_Id = ob_DokMagId
where datediff(year, dok_DataWyst, getdate()) <= {I: Nieużywano przez lat: 0}
group by ob_towid
) sprzedaz on sprzedaz.ob_towid=st_TowId
where (stan > 0 or   1 = {DB:select 0, 'Większy od zera' union all select 1, 'Dowolny':Stan magazynowy:1:Dowolny})
and sprzedaz.ob_towid is null


Poprawione, do testowania

Offline yemet

  • Zaawansowany użytkownik
  • ****
  • Wiadomości: 1271
  • Reputacja +46/-1
  • Wersja programu: Navireo
@MacKar
Coś mi się wydaje, że ten where datediff nie zadziała tak jak byś chciał  ;)

Offline MacKar

  • Nowy użytkownik
  • *
  • Wiadomości: 3
  • Reputacja +0/-0
  • Wersja programu: 1.7
@MacKar
Coś mi się wydaje, że ten where datediff nie zadziała tak jak byś chciał  ;)

Mógłbym poprosić, o trochę dokładniejsze wytłumaczenie? Jeżeli faktycznie jest tu błąd to chciałbym go poprawić, ale najpierw muszę go zrozumieć

Offline yemet

  • Zaawansowany użytkownik
  • ****
  • Wiadomości: 1271
  • Reputacja +46/-1
  • Wersja programu: Navireo
@MacKar
Coś mi się wydaje, że ten where datediff nie zadziała tak jak byś chciał  ;)

Mógłbym poprosić, o trochę dokładniejsze wytłumaczenie? Jeżeli faktycznie jest tu błąd to chciałbym go poprawić, ale najpierw muszę go zrozumieć

Jedyne co ten where zrobi to wytnie nowsze rekordy z selekcji i stracisz informację o tym, czy dany towar miał ruch po wskazanej dacie czy nie.
A ty nie chcesz nic wycinać, tylko sprawdzić datę ostatniego ruchu dla każdej pozycji i dopiero to odfiltrować. Czyli w ruch musi pójść MAX(data dokumentu/ruchu magazynowego) i HAVING.

Ja bym przepisał też te joiny bo to na dłuższą metę jest średnio czytelne. Zjoinuj tabele normalnie i wszystkie agregacje zrób w głównym SELECTcie. I zacznij korzystać z aliasów.

EDIT: Zostaw tak jak masz joina na stany towarowe bo inaczej wszystko się cudownie rozmnoży, resztę na oko można przepisać.
« Ostatnia zmiana: Maj 24, 2022, 10:40:44 wysłana przez yemet »

Offline birds22

  • Ekspert
  • *****
  • Wiadomości: 9228
  • Reputacja +1306/-21
  • Wersja programu: Najnowsza
Ja już dzisiaj po drugiej lampce jestem, ale tak na oko bez ssms wydaje mi się, że podzapytanie ze sprzedażą pokaże towary, które miały ruch magazynowy w okresie z datadiffa. Jeżeli połączmy je lewostronnie z kartoteką towarów i wybierzemy tylko te, które mają "and sprzedaz.ob_towid is null" to mamy towary, które się w danym okresie nie sprzedały.
Jedyne IMHO nie jest potrzebne to "group by ob_towid". Można było zrobić distinct ale nie wiem czy wydajnościowo to miałoby sens.


No chyba, że to wino jest za mocne albo ja już słabszą głowę mam :)
Sławek, Zduńska Wola

Offline yemet

  • Zaawansowany użytkownik
  • ****
  • Wiadomości: 1271
  • Reputacja +46/-1
  • Wersja programu: Navireo
Przyznam się, że też ssmsa nie odpalałem. Biomet nad morzem chyba jakiś dzisiaj niekorzystny ;D

Offline candy

  • Zaawansowany użytkownik
  • ****
  • Wiadomości: 4913
  • Reputacja +173/-11
zapytania SQL - produkty na ktorych nie bylo żadnego ruchu od jakiegoś czasu
« Odpowiedź #12 dnia: Maj 24, 2022, 21:31:20 »
Ja bym skorzystał z NOT EXISTS.
W końcu nie musimy wyliczac wszystkich pozycji ruchów towarowych, wystarczy stwierdzić że istnieje jakikolwiek ruch w wybranym okresie i już wiemy że warunek niespełniony.
Nie pytaj co rząd może zrobić dla Ciebie. Spytaj czy mógłby tego nie robić.

Offline birds22

  • Ekspert
  • *****
  • Wiadomości: 9228
  • Reputacja +1306/-21
  • Wersja programu: Najnowsza
Ja bym skorzystał z NOT EXISTS.
W końcu nie musimy wyliczać wszystkich pozycji ruchów towarowych, wystarczy stwierdzić że istnieje jakikolwiek ruch w wybranym okresie i już wiemy że warunek niespełniony.

No i namówiłeś mnie do włączenia komputera :)
Na bazie do której mam dostęp (ok 80.000 kartotek towarowych i  ~1.000.000 rekordów w dok_pozycja) czasy  z left join i not exists są porównywalne. Pewnie w innych układach danych mogłoby być różnie
Sławek, Zduńska Wola

Offline yemet

  • Zaawansowany użytkownik
  • ****
  • Wiadomości: 1271
  • Reputacja +46/-1
  • Wersja programu: Navireo
zapytania SQL - produkty na ktorych nie bylo żadnego ruchu od jakiegoś czasu
« Odpowiedź #14 dnia: Maj 24, 2022, 22:22:25 »
W oryginalnym pytaniu chodziło też w sumie o znalezienie towarów z zerowym stanem a warunek w zapytaniu @MacKar jest na stany większe od zera ale to pierdółka.

Można jeszcze dodatkowo dorzucić tw_zablokowany=0 żeby pominąć to co już jest nieaktywne.


U mnie też not exits i left join też wyszły bardzo podobnie - dużo mniej kartotek bo 13k ale w dok_pozycja ponad 6 mln.
Rzuciłem się jeszcze na tabelę dok_magruch. U mnie wykonało się to nieporównywalnie szybciej od podzapytania z dok_pozycja i dok__dokument.

Z dok_pozycja i dok_dokument jest jeszcze taki myk, że tam mogą być dokumenty i pozycje bez ruchu magazynowego, jakieś ZD, ZK, czy KFs / KFz cenowe i to może zrobić kuku w takim zapytaniu bez odfiltrowania tego odpowiednimi warunkami. Bez sprawdzania nie chcę rzucać tego jako absolutnego pewniaka ale dok_magruch chyba będzie bezpieczniejsze i szybsze.

EDIT: Dopiero teraz skojarzyłem, że odpytanie jest tutaj po ob_DokMagId więc te ZK i inne to nam wytnie ale zawsze zostanie kwestia wzięcia poprawki na wycofany lub odłożony skutek magazynowy.
« Ostatnia zmiana: Maj 24, 2022, 22:41:22 wysłana przez yemet »

Forum Użytkownikow Subiekt GT

zapytania SQL - produkty na ktorych nie bylo żadnego ruchu od jakiegoś czasu
« Odpowiedź #14 dnia: Maj 24, 2022, 22:22:25 »