Issue with using nested case conditions in Oracle SQL query - sql

i have a scenario where in , i need to calculate an employeee salary using a package , which gives me salary remaining for permanent employee if there is some prepayment and then convert the calculated value to a currency specified by the employee using another package.
How i have been doing this is:
CASE
WHEN ( ai.employee_type = 'PERMANENT' and ai.payment_status_flag='Y')
THEN EMP_UTILS_PKG.get_pay_amount_remaining( ai.employee_id )
ELSE ail.amount_remaining
END amount_remaining,
CASE
WHEN ( ai.salary_currency_code = NVL(find_currency('EMP_COMMON_CURRENCY'),ai.EMP_CURRENCY_CODE))
THEN CASE
WHEN ( ai.employee_type = 'PERMANENT' and ai.payment_status_flag='Y')
THEN EMP_UTILS_PKG.get_pay_amount_remaining( ai.employee_id )
ELSE ail.amount_remaining
END
ELSE EMP_API.convert_closest_amount_sql( x_from_currency => ai.EMP_CURRENCY_CODE ,x_to_currency => find_currency('EMP_COMMON_CURRENCY') ,x_amount =>( CASE
WHEN ( ai.employee_type = 'PERMANENT' and ai.payment_status_flag='Y')
THEN EMP_UTILS_PKG.get_pay_amount_remaining( ai.employee_id )
ELSE ail.amount_remaining
END) ,x_max_roll_days => -1)
END EMP_CONVERTED_AMOUNT_REMAINING,
I have repeated below condition 3 times in my query:
WHEN ( ai.employee_type = 'PERMANENT' and ai.payment_status_flag='Y')
THEN EMP_UTILS_PKG.get_pay_amount_remaining( ai.employee_id )
ELSE ail.amount_remaining
Is there a simpler approach for this, can we avoid repeating code like this?

You already use the function EMP_UTILS_PKG.get_pay_amount_remaining so why not create a PL/SQL function that encapsulates the logic and just call that in your multiple places.

You can use an inline view in the FROM clause to simplify this. Use the joins properly in your live code.
SELECT amount_remaining
, CASE
WHEN ai.salary_currency_code = NVL(find_currency('EMP_COMMON_CURRENCY')
,ai.EMP_CURRENCY_CODE)
THEN amount_remaining
ELSE EMP_API.convert_closest_amount_sql(
x_from_currency => ai.EMP_CURRENCY_CODE
,x_to_currency => find_currency('EMP_COMMON_CURRENCY')
,x_amount => amount_remaining
,x_max_roll_days => -1)
END EMP_CONVERTED_AMOUNT_REMAINING,
FROM (SELECT CASE
WHEN ai.employee_type = 'PERMANENT'
AND ai.payment_status_flag='Y'
THEN EMP_UTILS_PKG.get_pay_amount_remaining( ai.employee_id )
ELSE ail.amount_remaining
END amount_remaining
FROM table_name);

Related

Error "No column name was specified for column " " of "SOURCE" while select with case on merge

I am trying to select with case on merge in one of my pet projects and I ended up getting error.
I believe this is not the complete query, it is huge in number of lines and I can copy only this from the terminal. I thought maybe someone could help with this code and resolve my issue.
MERGE OrderDetails AS TARGET
USING
(
SELECT OrderHeader.OrderNo, SalesOrderData.[LineNo], SalesOrderData.WebOrderNo, SalesOrderData.quantity,ISNULL(SalesOrderData.BasePrice,'0') AS BasePrice,ISNULL(SalesOrderData.CustomPrice,'0') AS CustomPrice,
ISNULL(SalesOrderData.FinishingPrice,'0')AS FinishingPrice,ISNULL(SalesOrderData.NonDiscount2,'0') AS NonDiscountable, ISNULL(SalesOrderData.TotalPrice,'0') AS TotalPrice,
ISNULL(SalesOrderData.ExtendedPrice,'0') As ExtendedPrice,SalesOrderData.Category,SalesOrderData.StockNo,SalesOrderData.SSD,SalesOrderData.VerticalSS,SalesOrderData.LorH, SalesOrderData.WorB, SalesOrderData.Species,
SalesOrderData.FinishingOption, SalesOrderData.Grade, SalesOrderData.Sheen, SalesOrderData.FinishingBrand,SalesOrderData.ColorName,SalesOrderData.ColorNo,SalesOrderData.StockPaint,
CASE
WHEN SalesOrderData.Category = 'TL' THEN '1.125'
WHEN SalesOrderData.Category = 'RP' THEN '1.125'
WHEN SalesOrderData.Category = 'CTL' THEN '1.25'
WHEN SalesOrderData.Category = 'CTL-BAH' THEN '1.25'
WHEN SalesOrderData.Category = 'CRP' THEN '1.25'
WHEN SalesOrderData.Category = 'IRP' THEN '1.07'
Else SalesOrderData.[SS Thickness]
END
, SalesOrderData.BRD, SalesOrderData.TRD, SalesOrderData.CRD, SalesOrderData.CRD2, SalesOrderData.CRD3, SalesOrderData.CRP1,SalesOrderData.CRP2, SalesOrderData.CRP3, SalesOrderData.Section1, SalesOrderData.Section2,
SalesOrderData.Section3, SalesOrderData.Section4,
CASE
WHEN SalesOrderData.PanelType = 'NA' THEN '-'
Else SalesOrderData.PanelType
END
FROM SalesOrderData
INNER JOIN OrderHeader ON SalesOrderData.WebOrderNo = OrderHeader.WebOrderNo
INNER JOIN OrderDetails ON SalesOrderData.WebOrderNo = OrderDetails.WebOrderNo)
AS SOURCE
ON Source.WebOrderNo = Target.WebOrderNo
WHEN NOT MATCHED BY TARGET
THEN
INSERT
(OrderNo, [LineNo], WebOrderNo, Quantity,BasePrice, CustomPrice, FinishingPrice, NonDiscountable,TotalPrice,ExtendedPrice, Category,StockNo, SSD, VerticalSS,LorH, WorB, Species,FinishingOption, Grade, Sheen,
FinishingBrand, ColorName,ColorNo,StockPaint,SSthick, BRD, TRD, CRD, CRD2, CRD3, CRP1Req,CRP2Req, CRP3Req, Section1, Section2, Section3, Section4,PanelType, RailConfig, ItemText6,SStype, ArchLow, ArchHigh,
LouverDirection, TrimType, TrimLouverDirection,MHLouverDirection, FCRLouverDirection,MHTR,MHCR1,MHCR2,MHCR3,UM,VBoardWidth, VBoardTotal, HBoardWidth,VBoardSpacing,ShutterComments,Custom1,Custom2,Custom3,Custom4,Custom5)
VALUES
(Source.OrderNo,Source.[LineNo], Source.WebOrderNo, Source.Quantity,Source.BasePrice, Source.CustomPrice, Source.FinishingPrice, Source.NonDiscountable,Source.TotalPrice,Source.Source.ExtendedPrice, Source.Category,
Source.StockNo, Source.SSD, Source.VerticalSS,Source.LorH, Source.WorB, Source.Species, Source.FinishingOption, Source.Grade, Source.Sheen, Source.FinishingBrand, Source.ColorName,Source.ColorNo,Source.StockPaint,
Source.SSthick, Source.BRD, Source.TRD, Source.CRD, Source.CRD2, Source.CRD3, Source.CRP1Req,Source.CRP2Req, Source.CRP3Req, Source.Section1, Source.Section2, Source.Section3, Source.Section4,Source.PanelType,
Source.RailConfig, Source.ItemText6,Source.SStype, Source.ArchLow, Source.ArchHigh, Source.LouverDirection, Source.TrimType, Source.TrimLouverDirection,Source.MHLouverDirection, Source.FCRLouverDirection,Source.MHTR,
Source.MHCR1,Source.MHCR2,Source.MHCR3,Source.UM,Source.VBoardWidth, Source.VBoardTotal, Source.HBoardWidth,Source.VBoardSpacing,SSource.hutterComments,Source.Custom1,Source.Custom2,Source.Custom3,Source.Custom4,
Source.Custom5);
Your CASE expressions need aliases. You have, for example:
CASE
WHEN SalesOrderData.Category = 'TL' THEN '1.125'
...
ELSE SalesOrderData.[SS Thickness]
END
,
It needs to be:
SomeMeaningfulAlias = CASE
WHEN SalesOrderData.Category = 'TL' THEN '1.125'
...
ELSE SalesOrderData.[SS Thickness]
END
,
Or:
CASE
WHEN SalesOrderData.Category = 'TL' THEN '1.125'
...
ELSE SalesOrderData.[SS Thickness]
END AS SomeMeaningfulAlias
,

Materialized View blocking sessions

We have created a materialized view on Oracle 19c, but Insert/Update blocking session. Below is our materialized view:
CREATE MATERIALIZED VIEW MVIEW refresh force ON COMMIT as
Select P.Id QTable_Id, P.Tw_Id, P.NTable_Id,P.ROWID QTable_ROWID,M1.ROWID NTable_ROWID,SL1.ROWID SlTable_ROWID,SL2.ROWID SlTable2_ROWID,
Case When (P.NTable_Id Is Not Null) Then M1.SlTable_Id
When (P.SlTable_Id Is Not Null) Then P.SlTable_Id
Else '' -- When there is no SlTable_id
End As SlTable_Id ,
Case When (P.NTable_Id Is Not Null) Then
(
Case
When (M1.Sh_Id Is Not Null) Then M1.Sh_Id
When (M1.SlTable_Id Is Not Null) Then SL2.Sh_Id
Else ''
End
)
When (P.SlTable_Id Is Not Null) Then
(
Case
When ( SL1.Sh_Id Is Not Null) Then SL1.Sh_Id
Else ''
End
)
Else '' End As Sh_Id
From QTable P, NTable M1,SlTable SL1,SlTable Sl2
where
P.NTable_Id = M1.Id(+)
and P.SlTable_Id=SL1.Id(+)
and M1.SlTable_Id=Sl2.Id(+)

Float with Null case condition

In the below code, IN ELSE, what if I don't want to pass 'NOTEQUAL' and pass a NULL Value of Float
select from table as A {
A.objek,
max(case when A.atinn = '0000010530' then fltp_to_dec( A.atflv as abap.dec(5,3) else <what to enter here for null or no values > end ) as DDC
}
group by A.objek
If you need NULL then use NULL
select from table as A {
A.objek,
max(case when A.atinn = '0000010530'
then fltp_to_dec( A.atflv as abap.dec(5,3)
else NULL end ) as DDC
}
group by A.objek
or nothing as suggested by Larnu
select from table as A {
A.objek,
max(case when A.atinn = '0000010530'
then fltp_to_dec( A.atflv as abap.dec(5,3)
end ) as DDC
}
group by A.objek

Sql concatenate result on case

I have a table like this
Nomeutente|data |Controllo
----------|----------|---------
utente1 |11-11-2016|prova1
utente1 |11-11-2016|prova4
utente1 |11-11-2016|prova3
utente2 |11-11-2016|ricontrollo
utente2 |11-11-2016|ricontrollo2
utente2 |11-11-2016|ricontrollo3
utente3 |11-11-2016|ricontrollo3
utente4 |11-11-2016|ricontrollo3
and with case i create a query like a pivot
Select
BASE.data,
Max(Case BASE.Nomeutente When 'utente1' Then base.controllo Else ''
End) As utente1,
Max(Case BASE.Nomeutente When 'utente2' Then base.controllo Else ''
End) As utente2,
Max(Case BASE.Nomeutente When 'utente3' Then base.controllo Else ''
End) As utente3,
Max(Case BASE.Nomeutente When 'utente4' Then base.controllo Else ''
End) As utente4,
From
(Select
Nomeutente,
data,
controllo
From PROVA) As BASE
Group By
base.data
but I want in case that insert all controllo value like
Nomeutente|data |Controllo
----------|----------|---------
utente1 |11-11-2016| prova1,prova4,prova3
utente2 |11-11-2016| ricontrollo,ricontrollo2,ricontrollo3
utente3 |11-11-2016| ricontrollo3
utente4 |11-11-2016| ricontrollo3
what kind of query can I create for make this on postgresql 7.4 ?
First create aggregate (only once):
create aggregate textcat_all(
basetype = text,
sfunc = textcat,
stype = text,
initcond = ''
);
Then you can run:
select
Nomeutente,
"data",
textcat_all(Controllo || ',') as Controllo
from
<table_name>
group by
Nomeutente, "data";
Recommeded reading:
https://www.postgresql.org/docs/7.4/static/sql-createaggregate.html
https://www.postgresql.org/support/versioning/

how to cascade CASE sql inside the condition WHERE

I am searching for a word match for the variable- #TextSearchWord
I have a #SearchCriteria variable which may have 5 values!
According to that value, i choose from which field i have to search my word!
-so i need to cascade the "CASE" statement inside the "WHERE" statement only and like other samples here inside the select statement !
SELECT COUNT(WordID) AS WordQty
FROM itinfo_QuranArabicWordsAll
WHERE (SiteID = #SiteID)
AND (QuranID = #QuranID)
AND (SuraID BETWEEN #StrtSuraID AND #EndSuraID)
AND (VerseOrder BETWEEN #StrtVerseSortOrder AND #EndVerseSortOrder)
AND (
-- here is my problem :
CASE
WHEN (#SearchCriteria = 'DictNM') THEN (WordDictNM = #TextSearchWord )
ELSE CASE
WHEN (#SearchCriteria = 'DictNMAlif') THEN (WordDictNMAlif = #TextSearchWord)
...
END
END
)
You don't need a CASE statement for this.
SELECT COUNT(WordID) AS WordQty
FROM itinfo_QuranArabicWordsAll
WHERE (SiteID = #SiteID)
AND (QuranID = #QuranID)
AND (SuraID BETWEEN #StrtSuraID AND #EndSuraID)
AND (VerseOrder BETWEEN #StrtVerseSortOrder AND #EndVerseSortOrder)
AND (
(#SearchCriteria = 'DictNM' AND WordDictNM = #TextSearchWord )
OR (#SearchCriteria = 'DictNMAlif' AND WordDictNMAlif = #TextSearchWord)
...
)
SQL WHERE clauses: Avoid CASE, use Boolean logic.
....
AND(
( #SearchCriteria = 'DictNM' AND WordDictNM = #TextSearchWord )
OR ( #SearchCriteria = 'DictNMAlif' AND WordDictNMAlif = #TextSearchWord )
)