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
,
I have the following sample query which takes values from procedure parameters. The parameter can be either passed or default to null.
SELECT * FROM table
WHERE( table_term_code = '201931'
OR (table_term_code = '201931' and table_DETL_CODE ='CA02')
OR ( table_term_code = '201931' and table_ACTIVITY_DATE = sysdate)
OR ( table_term_code = '201931' and table_SEQNO = NULL));
i.e the user can input term code and not input any other parameter, or can input term code and table_DETL_CODE and not any other input parameter.
Same goes for the other 2 or conditions.
If a term code is passed and table_DETL_CODE is null, the query should return all the values for that term_code, whereas this query returns null.
Is there a way to achieve this without case or if conditions in PL/SQL?
If I understood you correctly, this might be what you're looking for:
select *
from your_table
where (table_term_code = :par_term_code or :par_term_code is null)
and (table_detl_code = :par_detl_code or :par_detl_code is null)
and (table_activity_date = :par_activity_date or :par_activity_date is null)
and (table_seqno = :par_seqno or :par_seqno is null)
The description seems to that you require user to enter table_term_code and then either none or exactly 1 of the other 3. If so then perhaps:
select *
from your_table
where table_term_code = :par_term_code
and ( (table_detl_code = :par_detl_code and :par_activity_date is null and :par_seqno is null)
or (table_activity_date = :par_activity_date and :par_detl_code is null and :par_seqno is null)
or (table_seqno = :par_seqno and :par_detl_code is null and :par_activity_date is null)
or (table_seqno is null and :par_detl_code is null and :par_activity_date is null)
);
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/
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 )
)
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);