Zapytanie SQL - grupowanie w odrębnych kolumnach

0

Witam.
Chciałbym zmodyfikować zapytanie SQL. Ma ono na celu wyświelenie stanów magazynowych dla wszystkich indeksów oraz wszystkich magazynów.
Domyślnie w wyniku ukazuje się kilka razy indeks i jego stan na danym magazynie.

Chciałbym, aby wynik wyglądał tak jak w załączniku nr. 2.
Wyświetlić chciałbym dany indeks, i w kolumnach poszczególne ilości na magazynach. Tak aby każdy indeks wyświetlił się tylko raz.

0

Wersja MSSQL by się jeszcze przydała, ale...operator PIVOT Ci pomoże.

Co to za baza jest w ogóle? Wygląda jakbym sam ją zaprojektował (poza nazwami tabel) ;-)

0

W tej chwili używam MSSQL 2014. Baza przechowuje dane gospodarki materiałowej w firmie. Potrzebujemy kilka raportów dotyczących sprzedaży oraz stanów magazynowych. Najbardziej zależy mi na wyniku opisanym w pierwszym poście. Aby dla każdego indeksu były kolumny ze stanami dla poszczególnych magazynów. Tak, aby indeks nie był drukowany kilka razy na liście

0

No to operator PIVOT + google i dasz radę.

0

W tej chwili coś takiego zadziałało:
select T0.ItemCode,max(T1.ItemName) ItemName,max(T0.OnHand) OnHand,max(T1.InvntryUom) InvntryUom,max(T1.BWeight1) Bweight1 ,max(case when T0.WshCode='MKTP' then T0.OnHand * T1.BWeight1 else null end) MKTP ,max(case when T0.WshCode='MRAK' then T0.OnHand * T1.BWeight1 else null end) MRAK ,max(case when T0.WshCode='MZMSR' then T0.OnHand * T1.BWeight1 else null end) MZMSR ,max(case when T0.WshCode='MZPAGO' then T0.OnHand * T1.BWeight1 else null end) MZPAGO
from OITW T0 inner join OITM T1 on T0.ItemCode = T1.ItemCode where T0.OnHand > 0 group by T0.ItemCode order by T0.ItemCode

0

Dobrze, coś takiego zadziała... ale to jest krzywe i na kolanie... Funkcje agregujące są kosztowne, używanie ich na lewi i prawo bez potrzeby nie jest dobrą praktyką.
Plan wykonania pewnie nie jest zbyt ładny, co?
Dlaczego nie skorzystasz z PIVOT?

Wracając do pytania, bo mam wrażenie że za mało powiedziałeś...
Dlaczego tam jest MAX(OnHand)? Na pewno tak ma być?
taka konstrukcja:

MAX(CASE when T0.WshCode = 'MKTP' then T0.OnHand * T1.BWeight1
             else null
        end) MKTP

to może być strzał w kolano - na pewno wiesz co robisz, czyli dokładnie wiesz jak Twoja baza danych traktuje wartości null w funkcjach agregujących (takich jak max)?

Jak dokładnie wygląda tabela OITW dla konkretnego ItemCode?
o coś mi się widzi, że ona wygląda tak:

ItemCode WshCode OnHand
1-01 MKTP 10
1-01 MRAK 20
1-01 MZMSR 30
1-01 MZPAGO 40
1-01 null 100
Czyli ilość dla konkretnego magazynu i tam gdzie w polu WshCode jest null jest to wartość dla wszystkich magazynów.
Czy tak jest?
0
wloochacz napisał(a):

Jak dokładnie wygląda tabela OITW dla konkretnego ItemCode?
o coś mi się widzi, że ona wygląda tak:

||=ItemCode||WshCode||OnHand
||1-01||MKTP||10
||1-01||MRAK||20
||1-01||MZMSR||30
||1-01||MZPAGO||40
||1-01||null||100
Czyli ilość dla konkretnego magazynu i tam gdzie w polu WshCode jest null jest to wartość dla wszystkich magazynów.
Czy tak jest?

W tym przypadku wygląda to tak:
http://www.tinypic.pl/y1oad8qczwet

Nie ma pola o nazwie null, gdzie sumowana jest wartość magazynów.

0
adamocozza8 napisał(a):

W tym przypadku wygląda to tak:
http://www.tinypic.pl/y1oad8qczwet

Nie ma pola o nazwie null, gdzie sumowana jest wartość magazynów.

OK.
I powiedz mi teraz tak - na cholerę używasz funkcji agregującej, skoro tam przypada dokładnie jeden wiersz dla jednego towaru na konkretny magazyn.
A więc po co robisz grupowanie, skoro to samo możesz uzyskać prostym rozbiciem danych na kolumny za pomocą CASE?

A najlepiej PIVOT - ale to po śniadaniu Ci napisze...

0

Ok. Usiąde to PIVOT i spróbuję to wykonać za jego pomocą

0

Za pomocą PIVOT można np. tak:

----------------------------------------------------------------
-- Generowanie przykładowych danych
----------------------------------------------------------------
declare @OITW table(ItemCode varchar(30), WhsCode varchar(30), OnHand money);
declare @OITM table(ItemCode varchar(30), ItemName varchar(30), BWeight1 money);

insert into @OITW(ItemCode, WhsCode, OnHand) values ('002-1308', 'MKTP', 10)
insert into @OITW(ItemCode, WhsCode, OnHand) values ('002-1308', 'MRAK', 20)
insert into @OITW(ItemCode, WhsCode, OnHand) values ('002-1308', 'MZMSR', 30)
insert into @OITW(ItemCode, WhsCode, OnHand) values ('002-1308', 'MZPAGO', 40)

insert into @OITM(ItemCode, ItemName, BWeight1) values ('002-1308', 'Jakiś towar', 12.025)

----------------------------------------------------------------
-- Właściwe zapytanie
----------------------------------------------------------------
select pvt.ItemCode, B.ItemName, 
       pvt.MKTP MKTPOnHand,
       pvt.MKTP * B.BWeight1 MKTPTotalWeight,
       pvt.MRAK MRAKOnHand,
       pvt.MRAK * B.BWeight1 MRAKTotalWeight,
       pvt.MZMSR MZMSROnHand,
       pvt.MZMSR * B.BWeight1 MZMSRTotalWeight,
       pvt.MZPAGO MZPAGOOnHand,
       pvt.MZPAGO * B.BWeight1 MZPAGOTotalWeight
 from @OITW A
 pivot(sum(A.OnHand) for A.WhsCode in (MKTP, MRAK, MZMSR, MZPAGO)) pvt
 inner join @OITM B on (B.ItemCode = pvt.ItemCode)

1 użytkowników online, w tym zalogowanych: 0, gości: 1