Witam
Mam problem z wyrażeniem SELECT i znajdującym się w nim warunku CASE.
Już się przekonałem że CASE działa tak że w momencie gdy pierwszy warunek jest prawdziwy nie sprawdza już reszty warunków.
Ale mam do napisania raport w którym obydwa warunki mogą być (i w praktyce często są) prawdziwe. W takim przypadku dostaje tylko rekordy spełniające pierwszy warunek.
Generalnie chodzi o to że zapytanie ma w kontekście transportu wyciągnąć:
RODZAJ_DODATKU - ten może wynikać automatycznie z cennika, lub być wprowadzony ręcznie przez użytkownika. W zależności od sytuacji wstawiana ma być wartość 'CENNIK' lub 'MANUALNIE'.
KOD_DODATKU - jeśli wynika z cennika wstawiana jest wartość 'SUMA DODATKOW Z CENNIKA', jeśli został wprowadzony manualnie przez użytkownika jego kod jest pobierany z odpowiedniej tabeli.
WARTOSC_DODATKU - pobierana w zależności od kodu dodatku z odpowiednich tabel.
Jak pisałem wyżej bardzo często jest tak że na danym transporcie występują obydwa rodzaje dodatku.
Poniżej przykładowe zapytania i wyniki:Uwzględnione tylko dodatki manualne:
SELECT
NUMER_ZT = TR.TR_NUMBER
, RODZAJ_DODATKU = case
when TBC.TBC_ID is not null then 'MANUALNIE'
when TR.TR_BONUS_COST is not null then 'CENNIK'
end
, KOD_DODATKU = case
when KOD_DODATKU_OA.MSG_TEXT is not NULL then KOD_DODATKU_OA.MSG_TEXT
when TR.TR_BONUS_COST is not NULL then 'SUMA DODATKOW Z CENNIKA'
end
, WARTOSC_DODATKU = case
when TBC.TBC_VALUE is not NULL then CAST (TBC.TBC_VALUE AS DECIMAL (15,2))
when TR.TR_BONUS_COST is not NULL then TR.TR_BONUS_COST
end
FROM TRANSPORT as TR with (nolock)
left join TRANSPORT_BONUS_COST as TBC with (nolock) on TR.TR_ID = TBC.TBC_TR
outer apply(
select top 1
MD.MSG_TEXT
from MESSAGE_DATA as MD with (nolock)
inner join DICTIONARY_DETAIL as DD with (nolock) on DD.DD_MSG_UID = MD.MSG_UID and MD.MSG_LANG = 1045
where TBC.TBC_DD_BONUS = DD.DD_ID
)KOD_DODATKU_OA
where TR.TR_NUMBER = 'TK14585'
Uwzględnione tylko dodatki wynikające z cennika:
SELECT
NUMER_ZT = TR.TR_NUMBER
, RODZAJ_DODATKU = case
when TR.TR_BONUS_COST is not null then 'CENNIK'
when TBC.TBC_ID is not null then 'MANUALNIE'
end
, KOD_DODATKU = case
when TR.TR_BONUS_COST is not NULL then 'SUMA DODATKOW Z CENNIKA'
when KOD_DODATKU_OA.MSG_TEXT is not NULL then KOD_DODATKU_OA.MSG_TEXT
end
, WARTOSC_DODATKU = case
when TR.TR_BONUS_COST is not NULL then TR.TR_BONUS_COST
when TBC.TBC_VALUE is not NULL then CAST (TBC.TBC_VALUE AS DECIMAL (15,2))
end
FROM TRANSPORT as TR with (nolock)
left join TRANSPORT_BONUS_COST as TBC with (nolock) on TR.TR_ID = TBC.TBC_TR
outer apply(
select top 1
MD.MSG_TEXT
from MESSAGE_DATA as MD with (nolock)
inner join DICTIONARY_DETAIL as DD with (nolock) on DD.DD_MSG_UID = MD.MSG_UID and MD.MSG_LANG = 1045
where TBC.TBC_DD_BONUS = DD.DD_ID
)KOD_DODATKU_OA
where TR.TR_NUMBER = 'TK14585'
Co więcej nie za bardzo rozumiem dlaczego w drugim przypadku dostaje pięć rekordów zamiast jednego, bo w tabeli TRANSPORT jest zawsze jeden rekord do każdego numeru transportu.
Docelowo wynikiem zapytania powinno być łącznie sześć rekordów - pięć z dodatkiem manualnym i jeden dodatkiem wynikającym z cennika.
Nie za bardzo wiem jak to połączyć w jedną całość.
Być może rozwiązaniem może być jakaś konstrukcja zapytania skorelowanego, ale nie wiem czy to dobry kierunek.
Proszę o pomoc i jakieś podpowiedzi.