'Case' inside another value condition - sql

I'm trying to do a CASE inside another CASE expression. Actually, the situation is:
(SELECT cmp_tubo
FROM qt_qts.res_tubo_serra
WHERE res_tubo_serra.cod_ordem_producao = ro.cod_ordem_producao AND res_tubo_serra.idc_tubo = ro.idc_tubo
AND res_tubo_serra.idc_serra != 0
) AS cmp_corte_ponta
What I need:
IF the value of "cmp_corte_ponta" = 0 THEN I'll need to do this search and replace the value of the "cmp_corte_ponta":
Select
(CASE serra.tip_corte
WHEN '1' THEN to_char(SERRA.CMP_CORTE)
ELSE 'NO'
END
) cmp_corte_ponta
from fl_qts.res_tubo_serra_feixe serra
IF the value of "cmp_corte_ponta" != 0, then the value must still the same.
What kind of syntax should I use?
Thx!
* EDITED CODE *
select
pla.cod_pedido,
pla.cod_aqa,
coalesce (
NULLIF(
(SELECT cmp_tubo
FROM qt_qts.res_tubo_serra
WHERE res_tubo_serra.cod_ordem_producao = ro.cod_ordem_producao
AND res_tubo_serra.idc_tubo = ro.idc_tubo
AND res_tubo_serra.idc_serra != 0)
, 0),
(SELECT
(CASE serra.tip_corte
WHEN '1' THEN SERRA.CMP_CORTE
ELSE 0
END)
FROM fl_qts.res_tubo_serra_feixe serra)) as cmp_corte_ponta,
pla.another_collum
FROM qt_qts.res_tubo_secao_od ro...
And the error now is:
"ORA-01427 - "single-row subquery returns more than one row".

ORIGINAL but messed up datatypes:
SELECT COALESCE(
NULLIF(
(SELECT cmp_tubo
FROM qt_qts.res_tubo_serra
WHERE res_tubo_serra.cod_ordem_producao = ro.cod_ordem_producao
AND res_tubo_serra.idc_tubo = ro.idc_tubo
AND res_tubo_serra.idc_serra != 0)
, 0),
SELECT
(CASE serra.tip_corte
WHEN '1' THEN to_char(SERRA.CMP_CORTE)
ELSE 'NO'
END) cmp_corte_ponta
FROM fl_qts.res_tubo_serra_feixe serra
)
EDIT corrected datatypes. NULLIF() and COALESCE() both need all argument types to be the same (perhaps coercion will take place):
SELECT COALESCE(
NULLIF(
(SELECT to_char(cmp_tubo)
FROM qt_qts.res_tubo_serra
WHERE res_tubo_serra.cod_ordem_producao = ro.cod_ordem_producao
AND res_tubo_serra.idc_tubo = ro.idc_tubo
AND res_tubo_serra.idc_serra != 0)
, '0'),
SELECT
(CASE serra.tip_corte
WHEN '1' THEN to_char(SERRA.CMP_CORTE)
ELSE 'NO'
END) cmp_corte_ponta
FROM fl_qts.res_tubo_serra_feixe serra
)

I might try some nested decode statements given the small amount of values you are dealing with:
(SELECT decode(cmp_tubo,
0, (SELECT decode(serra.tip_corte,
'1', to_char(serra.cmp_corte),
'NO')
FROM fl_qts.res_tubo_serra_feixe serra),
cmp_tubo)
FROM qt_qts.res_tubo_serra
WHERE res_tubo_serra.cod_ordem_producao = ro.cod_ordem_producao AND res_tubo_serra.idc_tubo = ro.idc_tubo
AND res_tubo_serra.idc_serra != 0
) AS cmp_corte_ponta

Related

SQL XML dd/mm/yyyy failing to return as string

I am working with a legacy system that only accepts dd/mm/yyyy in the XML for the data fields otherwise it mucks up the data entry.
I have tried every which way to attempt to force my data fields to display as dd/mm/yyyy, I have attempted to CONVERT to DATETIME 103, I have tried declaring it as a VARCHAR and everytime time it returns as 2018-05-11 for example.
How can I force the returned field to display as DD/MM/YYYY, this is a snippet of my code, excuse how messy it is unfortunately it is very linear and the system that accepts the XML is very basic.
SELECT TOP 1 1 'job/queue',
#Branch 'job/branch',
CASE WHEN myli.PolRef# IS NOT NULL THEN 'update-broomsrisk' ELSE 'create-broomsrisk' END 'parameters/yzt/char20.1',
SUBSTRING(#PolicyRef,1,6) 'broomsdata/broomsclient/bcm/refno',
#PolicyRef 'broomsdata/broomspolicy/bpy/refno',
CASE WHEN myli.PolRef# IS NOT NULL THEN myli.key# ELSE NULL END 'broomsdata/broomspolicy/myli/KEY',
(SELECT ISNULL(ct2.convictiondate,ct2.offencedate) FROM #ConvictionTable AS ct2 WHERE ct2.RowNo = 1) 'broomsdata/broomspolicy/myli/Date1',
(SELECT ct2.code FROM #ConvictionTable AS ct2 WHERE ct2.RowNo = 1) 'broomsdata/broomspolicy/myli/Code1',
(SELECT ct2.fine FROM #ConvictionTable AS ct2 WHERE ct2.RowNo = 1) 'broomsdata/broomspolicy/myli/Fine1',
(SELECT ct2.noofpoints FROM #ConvictionTable AS ct2 WHERE ct2.RowNo = 1) 'broomsdata/broomspolicy/myli/Points1',
(SELECT ISNULL(ct2.convictiondate,ct2.offencedate) FROM #ConvictionTable AS ct2 WHERE ct2.RowNo = 2) 'broomsdata/broomspolicy/myli/Date2',
(SELECT ct2.code FROM #ConvictionTable AS ct2 WHERE ct2.RowNo = 2) 'broomsdata/broomspolicy/myli/Code2',
(SELECT ct2.fine FROM #ConvictionTable AS ct2 WHERE ct2.RowNo = 2) 'broomsdata/broomspolicy/myli/Fine2',
(SELECT ct2.noofpoints FROM #ConvictionTable AS ct2 WHERE ct2.RowNo = 2) 'broomsdata/broomspolicy/myli/Points2',
(SELECT ISNULL(ct2.convictiondate,ct2.offencedate) FROM #ConvictionTable AS ct2 WHERE ct2.RowNo = 3) 'broomsdata/broomspolicy/myli/Date3',
(SELECT ct2.code FROM #ConvictionTable AS ct2 WHERE ct2.RowNo = 3) 'broomsdata/broomspolicy/myli/Code3',
(SELECT ct2.fine FROM #ConvictionTable AS ct2 WHERE ct2.RowNo = 3) 'broomsdata/broomspolicy/myli/Fine3',
(SELECT ct2.noofpoints FROM #ConvictionTable AS ct2 WHERE ct2.RowNo = 3) 'broomsdata/broomspolicy/myli/Points3',
(SELECT ISNULL(ct2.convictiondate,ct2.offencedate) FROM #ConvictionTable AS ct2 WHERE ct2.RowNo = 4) 'broomsdata/broomspolicy/myli/Date4',
(SELECT ct2.code FROM #ConvictionTable AS ct2 WHERE ct2.RowNo = 4) 'broomsdata/broomspolicy/myli/Code4',
(SELECT ct2.fine FROM #ConvictionTable AS ct2 WHERE ct2.RowNo = 4) 'broomsdata/broomspolicy/myli/Fine4',
(SELECT ct2.noofpoints FROM #ConvictionTable AS ct2 WHERE ct2.RowNo = 4) 'broomsdata/broomspolicy/myli/Points4'
FROM #ConvictionTable AS ct
LEFT OUTER JOIN [FIG-SQL-SRV].InfoCentre.dbo.ic_BD_MYLI AS myli ON ct.branch = myli.B# AND ct.policyRef = myli.PolRef#
FOR XML PATH('xmlexecute'), TYPE;
The Fields I'm trying to force are the 'Date1'/'Date2' etc. fields.
Cheers
Use CONVERT(varchar(10), YourDateColumn, 103). I think your mistake was trying to convert to a datetime (I'm guessing you tried CONVERT(datetime, YourDateColumn, 103)) while using a style code; date/time datatypes, in SQL Server, have no format. Trying to format them won't do anything.
For example: SELECT CONVERT(varchar(10), GETDATE(), 103); returns the varchar(10) value '11/05/2018'.
Edit: The below is to (temporary) assist the OP in showing how i create XML for OpenInterchange. The OP is using a lot of Sub Selects, something that doesn't help the speed of the query. I've highlighted, a couple of points for the OP to note as well:
SELECT K.Insco AS Insurer,
K.B# AS Branch,
K.PolRef# AS PolicyRef,
K.ClaimRef# AS ClaimRef,
--XML Generation starts here.
(SELECT(SELECT K.B# AS branch,
'OO' AS operator,
'PDF' AS printtype
FOR XML PATH('job'),TYPE),
(SELECT (SELECT 'update-claim' AS [Char20.1]
FOR XML PATH('yzt'),TYPE)
FOR XML PATH('parameters'),TYPE),
(SELECT (SELECT (SELECT K.Ref# AS Refno
FOR XML PATH('bcm'),TYPE)
FOR XML PATH('broomsclient'),TYPE),
(SELECT (SELECT K.PolRef# AS Refno
FOR XML PATH('bpy'),TYPE)
FOR XML PATH('broomspolicy'),TYPE),
(SELECT (SELECT K.ClaimRef# AS [Claim.No],
K.[Claim No] AS [Ins.Claim.Ref],
K.KGMSettled AS [Claim.Settled],
K.KGMReserve AS [Claim.Reserve],
K.KGMReserve + K.KGMSettled As [Claim.Amount],
K.KGMStatus AS [Stat.Desc],
CASE K.KGMStatus WHEN 'Settled' THEN 'SETT'
WHEN 'Ouststanding' THEN 'OUTS'
WHEN 'Declined' THEN 'DECL'
WHEN 'Not Taken up' THEN 'NTUP'
WHEN 'Withdrawn' THEN 'WITH' END AS [stat.code],
CONVERT(varchar(10),K.[Notified Date],103) AS [Date.repd], --First example of the dd/MM/yyyy format
CONVERT(varchar(10),K.[Loss Date],103) AS [Loss.date], --Another example of the dd/MM/yyyy format
CASE WHEN K.[Date Closed] IS NOT NULL THEN CONVERT(varchar(10), GETDATE(), 103) END AS [Stat.date], -- and another example of the dd/MM/yyyy format
CONVERT(varchar(10),K.[Date Closed],103) AS [Date.Settled], --you get the idea. :)
CASE WHEN K.[Date Closed] IS NOT NULL AND K.[Incident Type] = 'Windscreen' THEN 'Yes'
WHEN K.[Date Closed] IS NULL THEN ''
WHEN K.[NCB Decision] = 'Allowed' THEN 'Yes'
WHEN K.[NCB Decision] = 'Disallowed' THEN 'Yes' END AS [Settled.free]
/*
CASE WHEN K.[Date Closed] IS NOT NULL AND K.[Incident Type] = 'Windscreen' THEN 'Yes'
WHEN K.KGMReserve + K.KGMSettled = 0 AND K.[Date Closed] IS NOT NULL THEN 'Yes'
WHEN K.KGMReserve + K.KGMSettled > 0 AND K.[Date Closed] IS NOT NULL THEN 'No'
ELSE '' END AS [Settled.free]*/
FOR XML PATH('bch'),TYPE),
(SELECT K.BCAKey AS [KEY],
K.[Vehicle Reg# No] AS [Reg.no],
K.[Driver Name] AS [Driver],
K.[ AD Paid] AS [Pay.ad],
K.[AD Reserve] AS [Reserve.ad],
K.[TPD Paid] + K.[TPI Paid] AS [Pay.tp],
K.[TPD Reserve] + K.[TPI Reserve] AS [Reserve.tp],
--K.[TPI Paid] AS [Pay.others],
--K.[TPI Reserve] AS [Reserve.others],
0 AS [Pay.others],
0 AS [Reserve.others],
K.KGMSettled AS [Pay.total],
K.KGMReserve AS [Reserve.Total],
K.[Recovery] AS [Pay.recovs],
K.[AD Recovery Reserve] AS [Reserve.recovs],
'Updated by FileDrop Service. XML Generated on ' + CONVERT(varchar(10),GETDATE(),103) as [Remarks4]
FOR XML PATH('bca'),TYPE),
(SELECT CONVERT(varchar(10),GETDATE(),103) AS [date],
LEFT(CONVERT(varchar(10),GETDATE(),108),5) AS [time],
'OO' AS [op],
'FileDrop' AS [Name],
K.KGMSettled AS [Settled],
K.KGMReserve AS [Reserve],
K.KGMSettled + K.KGMReserve As [Total],
--CONVERT(varchar(10),K.DataToDate,103) AS [EffDate],
CASE WHEN K.KGMSettled != K.BCHSettled THEN 'Payment'
WHEN K.KGMReserve != K.BCHReserve THEN 'Reserve Adjustment'
ELSE 'Payment' END AS [Notes]
FOR XML PATH('clam'),TYPE)
FOR XML PATH('broomsclaim'),TYPE)
FOR XML PATH('broomsdata'),TYPE)
FOR XML PATH('xmlexecute'),TYPE) AS InputXML,
GETDATE() AS DateGenerated,
0 AS TestLoad
FROM KGMCGStandard_viw K
WHERE K.ClaimsFound = 1
AND K.KGMFound = 1
AND (K.KGMSettled != K.BCHSettled
OR K.KGMReserve != K.BCHReserve
OR (CONVERT(date,K.KGMClosure) != CONVERT(date,BCHClosure)
OR (K.KGMClosure IS NULL AND K.BCHClosure IS NOT NULL)
OR (K.KGMClosure IS NOT NULL AND K.BCHClosure IS NULL))
OR (CASE WHEN K.[Date Closed] IS NOT NULL AND K.[Incident Type] = 'Windscreen' THEN 'Yes'
WHEN K.[NCB Decision] = 'Allowed' THEN 'Yes'
WHEN K.[NCB Decision] = 'Disallowed' THEN 'No' END != K.Settled_Free
OR (K.[Date Closed] IS NULL AND K.Settled_free IS NULL)))
AND NOT EXISTS (SELECT 1
FROM AutoloadXML_tbl A
WHERE A.Branch = K.B#
AND A.PolicyRef = K.PolRef#
AND A.ClaimRef = K.ClaimRef#
AND (A.DateSubmitted IS NULL
OR A.Installed = 0))
ORDER BY K.ClaimRef# ASC;
Since you already figured out the date part I will leave that up to you but your query could be simplified majorly using conditional aggregation. I used square braces around the column names instead of single quotes. Sure those work but I consider that a bad habit because it is difficult to decide if it is a string literal or a column alias. I also prefer to use alias = but that is more a preference thing. I also prefer leading commas which is also a preference thing.
Pretty sure this query should do the same thing.
SELECT 1 as 'job/queue',
#Branch as 'job/branch',
CASE WHEN myli.PolRef# IS NOT NULL THEN 'update-broomsrisk' ELSE 'create-broomsrisk' END as 'parameters/yzt/char20.1',
SUBSTRING(#PolicyRef,1,6) as 'broomsdata/broomsclient/bcm/refno',
#PolicyRef as 'broomsdata/broomspolicy/bpy/refno',
CASE WHEN myli.PolRef# IS NOT NULL THEN myli.key# ELSE NULL END as 'broomsdata/broomspolicy/myli/KEY'
, [broomsdata/broomspolicy/myli/Date1] = max(case when ct.RowNo = 1 then ISNULL(ct.convictiondate, ct.offencedate) end)
, [broomsdata/broomspolicy/myli/Code1] = max(case when ct.RowNo = 1 then ct.code end)
, [broomsdata/broomspolicy/myli/Fine1] = max(case when ct.RowNo = 1 then ct.fine end)
, [broomsdata/broomspolicy/myli/Points1] = max(case when ct.RowNo = 1 then ct.noofpoints end)
, [broomsdata/broomspolicy/myli/Date2] = max(case when ct.RowNo = 2 then ISNULL(ct.convictiondate, ct.offencedate) end)
, [broomsdata/broomspolicy/myli/Code2] = max(case when ct.RowNo = 2 then ct.code end)
, [broomsdata/broomspolicy/myli/Fine2] = max(case when ct.RowNo = 2 then ct.fine end)
, [broomsdata/broomspolicy/myli/Points] = max(case when ct.RowNo = 2 then ct.noofpoints end)
, [broomsdata/broomspolicy/myli/Date3] = max(case when ct.RowNo = 3 then ISNULL(ct.convictiondate, ct.offencedate) end)
, [broomsdata/broomspolicy/myli/Code3] = max(case when ct.RowNo = 3 then ct.code end)
, [broomsdata/broomspolicy/myli/Fine3] = max(case when ct.RowNo = 3 then ct.fine end)
, [broomsdata/broomspolicy/myli/Points3] = max(case when ct.RowNo = 3 then ct.noofpoints end)
, [broomsdata/broomspolicy/myli/Date4] = max(case when ct.RowNo = 4 then ISNULL(ct.convictiondate, ct.offencedate) end)
, [broomsdata/broomspolicy/myli/Code4] = max(case when ct.RowNo = 4 then ct.code end)
, [broomsdata/broomspolicy/myli/Fine4] = max(case when ct.RowNo = 4 then ct.fine end)
, [broomsdata/broomspolicy/myli/Points4] = max(case when ct.RowNo = 4 then ct.noofpoints end)
FROM #ConvictionTable AS ct
LEFT OUTER JOIN [FIG-SQL-SRV].InfoCentre.dbo.ic_BD_MYLI AS myli ON ct.branch = myli.B# AND ct.policyRef = myli.PolRef#
GROUP BY #Branch
, CASE WHEN myli.PolRef# IS NOT NULL THEN 'update-broomsrisk' ELSE 'create-broomsrisk' END
, SUBSTRING(#PolicyRef,1,6)
, #PolicyRef
, CASE WHEN myli.PolRef# IS NOT NULL THEN myli.key# ELSE NULL END
FOR XML PATH('xmlexecute'), TYPE

SQL code reduction

The below SQL code is in the where clause. Is there any other way that we can write to cut short this.The below code is repeating many times. I wanted to cut short this code
((Business_Unit = 'A'
and ((
convert(money, case when substring(ltrim(rtrim(premium_change)),len(ltrim(rtrim(premium_change))),1 ) = '-'
then substring(ltrim(rtrim(premium_change)),1,len(ltrim(rtrim(premium_change))) -1) else
substring(ltrim(rtrim(premium_change)),1,len(ltrim(rtrim(premium_change)))) end)
) >= 100))
OR
(Business_Unit = 'B'
AND ((
convert(money, case when substring(ltrim(rtrim(premium_change)),len(ltrim(rtrim(premium_change))),1 ) = '-'
then substring(ltrim(rtrim(premium_change)),1,len(ltrim(rtrim(premium_change))) -1) else
substring(ltrim(rtrim(premium_change)),1,len(ltrim(rtrim(premium_change)))) end)
) >=100.00)
AND (text7 != 'N')
OR
Business_Unit = 'B'
AND ((
convert(money, case when substring(ltrim(rtrim(premium_change)),len(ltrim(rtrim(premium_change))),1 ) = '-'
then substring(ltrim(rtrim(premium_change)),1,len(ltrim(rtrim(premium_change))) -1) else
substring(ltrim(rtrim(premium_change)),1,len(ltrim(rtrim(premium_change)))) end)
) >=100.00)
AND (text7 = 'N')
and (text4 != '')
OR Business_Unit = 'B'
AND ((
convert(money, case when substring(ltrim(rtrim(premium_change)),len(ltrim(rtrim(premium_change))),1 ) = '-'
then substring(ltrim(rtrim(premium_change)),1,len(ltrim(rtrim(premium_change))) -1) else
substring(ltrim(rtrim(premium_change)),1,len(ltrim(rtrim(premium_change)))) end)
) > 300.00)
AND (text7 = 'N')
and (text4 = ''))
OR
(Business_Unit = 'C'
and ((
convert(money, case when substring(ltrim(rtrim(premium_change)),len(ltrim(rtrim(premium_change))),1 ) = '-'
then substring(ltrim(rtrim(premium_change)),1,len(ltrim(rtrim(premium_change))) -1) else
substring(ltrim(rtrim(premium_change)),1,len(ltrim(rtrim(premium_change)))) end)
) >= 150)`enter code here`
and text1 != 'N')
I would use a CTE here. The idea is to prepare the data for your where clause:
;with cte as
(--your current query here without where clasuse
--just add the following to the select list
convert(money, case when substring(ltrim(rtrim(premium_change)),
len(ltrim(rtrim(premium_change))),
1) = '-'
then substring(ltrim(rtrim(premium_change)), 1,
len(ltrim(rtrim(premium_change)))
- 1)
else substring(ltrim(rtrim(premium_change)), 1,
len(ltrim(rtrim(premium_change))))
end) as pc
)
select * from cte
where
(Business_Unit = 'A' and pc >= 100) or
(Business_Unit = 'B' and pc >= 100 and text7 != 'N') or
...
I am failing to parse your weird AND OR combinations(that seems incorrect anyway).
If using a CTE is not possible you can shorten the following:
substring(ltrim(rtrim(premium_change)),len(ltrim(rtrim(premium_change))),1 )
becomes:
right(ltrim(rtrim(premium_change)), 1 )
and:
substring(ltrim(rtrim(premium_change)),1,len(ltrim(rtrim(premium_change))) -1)
becomes:
left(ltrim(rtrim(premium_change)), len(ltrim(rtrim(premium_change))) -1)
and:
substring(ltrim(rtrim(premium_change)),1,len(ltrim(rtrim(premium_change))))
becomes:
ltrim(rtrim(premium_change))

ERROR ORA-00905: missing keyword (microsoft ole db provider for oracle)

can anyone see what keyword is missing from the pl/sql query below?
I am getting the error ORA-00905: missing keyword (microsoft ole db provider for oracle)
not sure what keyword is missing - this is an odbc query to oracle database
SELECT "STAT"."ORD"."SAMPLEID",
MAX(CASE WHEN "STAT"."ORDANAEL"."MC"='QAERS' THEN N"STAT"."ORDANAEL"."RES_TXT" ELSE
'' END) AS ERSID,
"STAT"."ORDMCSTP_V"."SEQNB", "STAT"."ORD"."ORDPATNAME",
"STAT"."ORD"."ORDPATBIRTHDT", "STAT"."ORD"."CORORDNB", "STAT"."ORD"."PROJNB",
Max(CASE WHEN "STAT"."ORDANAEL"."MC"='AMMOL' THEN 'AMMOL'
WHEN "STAT"."ORDANAEL"."MC"='AMMOLR' THEN 'AMMOLR' ELSE '' END) AS TEST,
Max(CASE WHEN "STAT"."ORDANAEL"."MC"='AMMOL' THEN N"STAT"."ORDRESMCEL"."MC_RES"
WHEN "STAT"."ORDANAEL"."MC"='AMMOLR' THEN N"STAT"."ORDRESMCEL"."MC_RES" ELSE ''
END) AS MC_RES,
Max( CASE WHEN "STAT"."ORDMCSTP_V"."STEPMC"='AMIMI' THEN N"STAT"."ORDMCSTPEL"."RES"
ELSE '' END) AS IMI,
Max( CASE WHEN "STAT"."ORDMCSTP_V"."STEPMC"='AMIMP' THEN N"STAT"."ORDMCSTPEL"."RES"
ELSE '' END) AS IMP,
Max( CASE WHEN "STAT"."ORDMCSTP_V"."STEPMC"='AMNDM' THEN N "STAT"."ORDMCSTPEL"."RES"
ELSE '' END) AS NDM,
Max( CASE WHEN "STAT"."ORDMCSTP_V"."STEPMC"='AMOX48' THEN
N "STAT"."ORDMCSTPEL"."RES" ELSE '' END) AS OXA48,
Max( CASE WHEN "STAT"."ORDMCSTP_V"."STEPMC"='AMSPM' THEN N "STAT"."ORDMCSTPEL"."RES"
ELSE '' END) AS SPM,
Max( CASE WHEN "STAT"."ORDMCSTP_V"."STEPMC"='AMVIM' THEN N "STAT"."ORDMCSTPEL"."RES"
ELSE '' END) AS VIM,
Max( CASE WHEN "STAT"."ORDMCSTP_V"."STEPMC"='AMDIM' THEN N "STAT"."ORDMCSTPEL"."RES"
ELSE '' END) AS DIM,
Max( CASE WHEN "STAT"."ORDMCSTP_V"."STEPMC"='AMKPC' THEN N "STAT"."ORDMCSTPEL"."RES"
ELSE '' END) AS KPC,
Max( CASE WHEN "STAT"."ORDMCSTP_V"."STEPMC"='AMGES' THEN N "STAT"."ORDMCSTPEL"."RES"
ELSE '' END) AS GES,
Max( CASE WHEN "STAT"."ORDMCSTP_V"."STEPMC"='AMSME' THEN N "STAT"."ORDMCSTPEL"."RES"
ELSE '' END) AS SME,
Max( CASE WHEN "STAT"."ORDMCSTP_V"."STEPMC"='AMFRI1' THEN
N "STAT"."ORDMCSTPEL"."RES" ELSE '' END) AS FRI1,
Max( CASE WHEN "STAT"."ORDMCSTP_V"."STEPMC"='AMSIM' THEN N "STAT"."ORDMCSTPEL"."RES"
ELSE '' END) AS SIM,
Max( CASE WHEN "STAT"."ORDMCSTP_V"."STEPMC"='AMGIM' THEN N "STAT"."ORDMCSTPEL"."RES"
ELSE '' END) AS GIM,
Max( CASE WHEN "STAT"."ORDANAEL"."MC"='AMMOL' THEN N "STAT"."ORDANAEL"."VALMED" ELSE
'' END) AS VALMED_AMMOL,
Max( CASE WHEN "STAT"."ORDANAEL"."MC"='AMMOL' AND
"STAT"."ORDANAEL_D"."DFIELD"='RR' THEN N "STAT"."ORDANAEL_D"."DVALUE" ELSE '' END)
AS RPT_DT_AMMOL,
"STAT"."ORDANAEL"."RES_ST"
FROM (("STAT"."ORDMCSTPEL" INNER JOIN ("STAT"."ORDMCSTP_V" INNER JOIN
("STAT"."ORD" INNER JOIN "STAT"."ORDANAEL" ON ("STAT"."ORD"."LID" =
"STAT"."ORDANAEL"."LID") AND ("STAT"."ORD"."LPERIOD" =
"STAT"."ORDANAEL"."LPERIOD") AND ("STAT"."ORD"."ORDNB" =
"STAT"."ORDANAEL"."ORDNB")) ON ("STAT"."ORDMCSTP_V"."LID" = "STAT"."ORD"."LID")
AND ("STAT"."ORDMCSTP_V"."LPERIOD" = "STAT"."ORD"."LPERIOD") AND
("STAT"."ORDMCSTP_V"."ORDNB" = "STAT"."ORD"."ORDNB")) ON ("STAT"."ORDMCSTPEL"."BC"
= "STAT"."ORDMCSTP_V"."BC") AND ("STAT"."ORDMCSTPEL"."CURRENT_STEPNB" =
"STAT"."ORDMCSTP_V"."CURRENT_STEPNB")) INNER JOIN "STAT"."ORDANAEL_D" ON
("STAT"."ORDANAEL"."NBINT" = "STAT"."ORDANAEL_D"."DNBINT") AND
("STAT"."ORDANAEL"."SPSEQ" = "STAT"."ORDANAEL_D"."DSPSEQ") AND
("STAT"."ORDANAEL"."ORDNB" = "STAT"."ORDANAEL_D"."DORDNB") AND
("STAT"."ORDANAEL"."LPERIOD" = "STAT"."ORDANAEL_D"."DLPERIOD") AND
("STAT"."ORDANAEL"."LID" = "STAT"."ORDANAEL_D"."DLID")) INNER JOIN
"STAT"."ORDRESMCEL" ON ("STAT"."ORDMCSTP_V"."SEQNB" = "STAT"."ORDRESMCEL"."SEQNB")
AND ("STAT"."ORDANAEL"."ORDNB" = "STAT"."ORDRESMCEL"."ORDNB") AND
("STAT"."ORDANAEL"."LPERIOD" = "STAT"."ORDRESMCEL"."LPERIOD") AND
("STAT"."ORDANAEL"."LID" = "STAT"."ORDRESMCEL"."LID")
WHERE (("STAT"."ORD"."LID")='H1')
AND (("STAT"."ORD"."LPERIOD")>'5200')
AND (("STAT"."ORD"."PROJNB")='ACPOERS')
GROUP BY "STAT"."ORD"."SAMPLEID", "STAT"."ORDMCSTP_V"."SEQNB",
"STAT"."ORD"."ORDPATNAME", "STAT"."ORD"."ORDPATBIRTHDT", "STAT"."ORD"."CORORDNB",
"STAT"."ORD"."PROJNB", "STAT"."ORDANAEL"."RES_ST"
HAVING ((("STAT"."ORDMCSTP_V"."SEQNB") Is Not Null) AND (("STAT"."ORD"."PROJNB")
='ACPOERS') AND (("STAT"."ORDANAEL"."RES_ST")>'4'))
Just too big for comment. Just cleaned up the double quotes and the N and it comes clean in a SQL formatter.
SELECT STAT.ORD.SAMPLEID,
MAX ( CASE WHEN STAT.ORDANAEL.MC = 'QAERS' THEN STAT.ORDANAEL.RES_TXT ELSE '' END ) AS ersid,
STAT.ORDMCSTP_V.SEQNB,
STAT.ORD.ORDPATNAME,
STAT.ORD.ORDPATBIRTHDT,
STAT.ORD.CORORDNB,
STAT.ORD.PROJNB,
MAX (
CASE
WHEN STAT.ORDANAEL.MC = 'AMMOL' THEN 'AMMOL'
WHEN STAT.ORDANAEL.MC = 'AMMOLR' THEN 'AMMOLR'
ELSE ''
END )
AS test,
MAX (
CASE
WHEN STAT.ORDANAEL.MC = 'AMMOL' THEN STAT.ORDRESMCEL.MC_RES
WHEN STAT.ORDANAEL.MC = 'AMMOLR' THEN STAT.ORDRESMCEL.MC_RES
ELSE ''
END )
AS mc_res,
MAX ( CASE WHEN STAT.ORDMCSTP_V.STEPMC = 'AMIMI' THEN STAT.ORDMCSTPEL.RES ELSE '' END ) AS imi,
MAX ( CASE WHEN STAT.ORDMCSTP_V.STEPMC = 'AMIMP' THEN STAT.ORDMCSTPEL.RES ELSE '' END ) AS imp,
MAX ( CASE WHEN STAT.ORDMCSTP_V.STEPMC = 'AMNDM' THEN STAT.ORDMCSTPEL.RES ELSE '' END ) AS ndm,
MAX ( CASE WHEN STAT.ORDMCSTP_V.STEPMC = 'AMOX48' THEN STAT.ORDMCSTPEL.RES ELSE '' END ) AS oxa48,
MAX ( CASE WHEN STAT.ORDMCSTP_V.STEPMC = 'AMSPM' THEN STAT.ORDMCSTPEL.RES ELSE '' END ) AS spm,
MAX ( CASE WHEN STAT.ORDMCSTP_V.STEPMC = 'AMVIM' THEN STAT.ORDMCSTPEL.RES ELSE '' END ) AS vim,
MAX ( CASE WHEN STAT.ORDMCSTP_V.STEPMC = 'AMDIM' THEN STAT.ORDMCSTPEL.RES ELSE '' END ) AS dim,
MAX ( CASE WHEN STAT.ORDMCSTP_V.STEPMC = 'AMKPC' THEN STAT.ORDMCSTPEL.RES ELSE '' END ) AS kpc,
MAX ( CASE WHEN STAT.ORDMCSTP_V.STEPMC = 'AMGES' THEN STAT.ORDMCSTPEL.RES ELSE '' END ) AS ges,
MAX ( CASE WHEN STAT.ORDMCSTP_V.STEPMC = 'AMSME' THEN STAT.ORDMCSTPEL.RES ELSE '' END ) AS sme,
MAX ( CASE WHEN STAT.ORDMCSTP_V.STEPMC = 'AMFRI1' THEN STAT.ORDMCSTPEL.RES ELSE '' END ) AS fri1,
MAX ( CASE WHEN STAT.ORDMCSTP_V.STEPMC = 'AMSIM' THEN STAT.ORDMCSTPEL.RES ELSE '' END ) AS sim,
MAX ( CASE WHEN STAT.ORDMCSTP_V.STEPMC = 'AMGIM' THEN STAT.ORDMCSTPEL.RES ELSE '' END ) AS gim,
MAX ( CASE WHEN STAT.ORDANAEL.MC = 'AMMOL' THEN STAT.ORDANAEL.VALMED ELSE '' END )
AS valmed_ammol,
MAX ( CASE
WHEN STAT.ORDANAEL.MC = 'AMMOL'
AND STAT.ORDANAEL_D.DFIELD = 'RR' THEN
STAT.ORDANAEL_D.DVALUE
ELSE
''
END )
AS rpt_dt_ammol,
STAT.ORDANAEL.RES_ST
FROM ((STAT.ORDMCSTPEL
INNER JOIN (STAT.ORDMCSTP_V
INNER JOIN (STAT.ORD
INNER JOIN STAT.ORDANAEL
ON ( STAT.ORD.LID = STAT.ORDANAEL.LID )
AND ( STAT.ORD.LPERIOD = STAT.ORDANAEL.LPERIOD )
AND ( STAT.ORD.ORDNB = STAT.ORDANAEL.ORDNB ))
ON ( STAT.ORDMCSTP_V.LID = STAT.ORD.LID )
AND ( STAT.ORDMCSTP_V.LPERIOD = STAT.ORD.LPERIOD )
AND ( STAT.ORDMCSTP_V.ORDNB = STAT.ORD.ORDNB ))
ON ( STAT.ORDMCSTPEL.BC = STAT.ORDMCSTP_V.BC )
AND ( STAT.ORDMCSTPEL.CURRENT_STEPNB = STAT.ORDMCSTP_V.CURRENT_STEPNB ))
INNER JOIN STAT.ORDANAEL_D
ON ( STAT.ORDANAEL.NBINT = STAT.ORDANAEL_D.DNBINT )
AND ( STAT.ORDANAEL.SPSEQ = STAT.ORDANAEL_D.DSPSEQ )
AND ( STAT.ORDANAEL.ORDNB = STAT.ORDANAEL_D.DORDNB )
AND ( STAT.ORDANAEL.LPERIOD = STAT.ORDANAEL_D.DLPERIOD )
AND ( STAT.ORDANAEL.LID = STAT.ORDANAEL_D.DLID ))
INNER JOIN STAT.ORDRESMCEL
ON ( STAT.ORDMCSTP_V.SEQNB = STAT.ORDRESMCEL.SEQNB )
AND ( STAT.ORDANAEL.ORDNB = STAT.ORDRESMCEL.ORDNB )
AND ( STAT.ORDANAEL.LPERIOD = STAT.ORDRESMCEL.LPERIOD )
AND ( STAT.ORDANAEL.LID = STAT.ORDRESMCEL.LID )
WHERE ( ( STAT.ORD.LID ) = 'H1' )
AND ( ( STAT.ORD.LPERIOD ) > '5200' )
AND ( ( STAT.ORD.PROJNB ) = 'ACPOERS' )
GROUP BY STAT.ORD.SAMPLEID,
STAT.ORDMCSTP_V.SEQNB,
STAT.ORD.ORDPATNAME,
STAT.ORD.ORDPATBIRTHDT,
STAT.ORD.CORORDNB,
STAT.ORD.PROJNB,
STAT.ORDANAEL.RES_ST
HAVING ( ( ( STAT.ORDMCSTP_V.SEQNB ) IS NOT NULL )
AND ( ( STAT.ORD.PROJNB ) = 'ACPOERS' )
AND ( ( STAT.ORDANAEL.RES_ST ) > '4' ) );
You can use N in front of a string literal to mark it as an nvarchar2. Example:
select N'abc' from dual
But you can't use it in front of an identifier the way you are doing it. If you want to read a certain column value as an nvarchar2, you'll need to cast it as such. Example:
... THEN cast("STAT"."ORDANAEL"."RES_TXT" as nvarchar2(50)) ...

A subquery in a select causes my results to not return

Hello I have an issue with a very convoluted query, I did not write the query but I have to maintain it.
I have the below super long query which was working fine for a while(slow but fine) but some time in the last month it stopped working. we don't get an error it just times out returning results.
Now, if I run this fun query below with the first sub query within the selection criteria removed the results return the top 50 in 136 seconds.
If I leave it in it just times out after a few hours. Also to note if I take the sub query in the select statement and run it on it's own hard coding any values passed in to it returns the result in 0.004 seconds.
If I leave it all in but go to the very core query in this long query and put a restriction on the SDDOCO so it will return a single result I get the result in 94 seconds and it doesn't matter if I have the sub query in the select or not.
I think that one of the results is causing issues and bogging down the query but I can't think of a good way to figure out which item would cause this.. my result set when it returns is 47k records.
Any suggestions on where I can look or how I can investigate this further would be greatly appreciated.
SELECT
SUM((GL.GLAA/100) * (CAST(COALESCE((Select CXCRR from PRODDTA.F0015 F2 WHERE CXEFT = (SELECT MAX(CXEFT) FROM PRODDTA.F0015 F3 WHERE F3.CXEFT <= GL.GLDGJ) and CXCRCD = GL.GLCRCD AND CXCRDC ='USD'), 1) AS NUMERIC(15,4)))) TEST1,
SUM((GL.GLAA/100)) test2
FROM (SELECT MAX(SDAN8) SDAN8, MAX(SDMCU) SDMCU, MAX(SDDOCO) SDDOCO, MAX(SDDOC) SDDOC, MAX(SDSHAN) SDSHAN, CASE WHEN NVL(TRIM(TMURRF),' ') = ' ' then SDURRF ELSE TMURRF END SDURRF, MAX(SDDCTO) SDDCTO, MAX(SDDGL) SDDGL, MAX(SDASN) SDASN
, SUM(CASE WHEN IMGLPT like 'FG%' THEN (CASE WHEN NOT (UMCONV IS NULL) THEN SDSOQS/100 * UMCONV/10000000 else SDSOQS/100 END) ELSE 0 END) AS SDSOQS
, SUM(CASE WHEN IMGLPT = 'FG04' THEN (CASE WHEN NOT (UMCONV IS NULL) THEN SDSOQS/100 * UMCONV/10000000 ELSE SDSOQS/100 END) ELSE 0 END) AS AER_SDSOQS
, SUM(CASE WHEN IMGLPT like 'FG%' THEN (CASE WHEN SDSRP5 = '527' THEN (CASE WHEN NOT (UMCONV IS NULL) THEN SDSOQS/100 * UMCONV/10000000 ELSE SDSOQS/100 END) ELSE 0 END) ELSe 0 END) AS MDJ_SDSOQS
, MAX(SDIVD) SDIVD, MAX(SDADDJ) SDADDJ
, SUM(CASE WHEN SDWTUM = 'LB' THEN SDITWT WHEN UCCONV is not null then SDITWT*(UCCONV/10000000) WHEN CONV is not null THEN SDSOQS*CONV*10 ELSE 0 END)/10000 AS WEIGHT
,SUM(CASE WHEN IMGLPT like 'FG%' THEN
CASE
WHEN SDWTUM = 'LB' THEN SDITWT
WHEN UCCONV IS NOT NULL THEN SDITWT*(UCCONV/10000000)
WHEN CONV is not null THEN SDSOQS*CONV*10
ELSE 0 END
ELSE 0
end)/10000 as FG_WEIGHT,
SUM(CASE WHEN IMGLPT = 'FG04' THEN
CASE
WHEN SDWTUM = 'LB' THEN SDITWT
WHEN UCCONV IS NOT NULL THEN SDITWT*(UCCONV/10000000)
WHEN CONV is not null THEN SDSOQS*CONV*10
ELSE 0 END
ELSE 0
end)/10000 as AER_WEIGHT,
SUM(CASE WHEN SDSRP5 = '527' THEN
CASE
WHEN SDWTUM = 'LB' THEN SDITWT
WHEN UCCONV IS NOT NULL THEN SDITWT*(UCCONV/10000000)
WHEN CONV is not null THEN SDSOQS*CONV*10
ELSE 0 END
ELSE 0
end)/10000 as MDJ_WEIGHT,
SUM(CASE WHEN IMGLPT = 'FG07' THEN
CASE
WHEN SDWTUM = 'LB' THEN SDITWT
WHEN UCCONV IS NOT NULL THEN SDITWT*(UCCONV/10000000)
WHEN CONV is not null THEN SDSOQS*CONV*10
ELSE 0 END
ELSE 0
end)/10000 as MDJ_3rdParty_WEIGHT, max(SDCARS) SDCARS
FROM PRODDTA.F42119
left join proddta.F554202x on trim(SDURRF) = trim(TMUSRRSV1) and SDDOCO = TMDOCO
LEFT JOIN PRODDTA.F4101 ON IMITM = SDITM
LEFT JOIN PRODDTA.F41002 ON UMITM = SDITM AND SDMCU = UMMCU AND SDUOM = UMUM AND UMRUM = imuom1
left join PRODDTA.F41003 on UCUM = SDWTUM and UCRUM = 'LB'
Left JOin (SELECT UMMCU as MCU, UMITM as ITM, UMUM as UM, max(CASE WHEN UMRUM = 'LB' THEN UMCONV/10000000 ELSE UMCONV/10000000 * UCCONV/10000000 END) AS CONV
FROM PRODDTA.F41002
LEFT JOIN PRODDTA.F41003
ON UMRUM = UCUM
WHERE (UCRUM = 'LB' OR UMRUM = 'LB')
GROUP BY UMMCU, UMITM, UMUM) CONV2
ON MCU = SDMCU AND ITM = SDITM AND UM = SDUOM
WHERE SDLNTY = 'S'
AND SDSOQS > 0
and not ((SDLTTR = 980 AND SDNXTR = 999) OR SDSOCN = SDUORG)
and SDSRP1 <> 'BLK'
and not exists (select SDDOCO from proddta.F42119 GA where SDADDJ >= FISCALPERIODSTART(14,1) and SDADDJ <= FISCALPERIODEND(14,12) and SDUOM = 'GA' and F42119.SDDOCO = GA.SDDOCO)
and SDDOCO in (1230256,1227461,1230628,1225291,1225297,1231601,1242703,1248671,1249556,1244905)
GROUP BY CASE WHEN NVL(TRIM(TMURRF),' ') = ' ' then SDURRF ELSE TMURRF END) DTL
Left JOIN PRODDTA.F0101 BT ON BT.ABAN8 = DTL.SDAN8
Left JOIN PRODDTA.F0101 ST ON ST.ABAN8 = DTL.SDSHAN
INNER JOIN PRODDTA.F0911 GL
ON TRIM(GL.GLEXR) = TRIM(DTL.SDURRF)
WHERE GLDCT = 'PV' AND GLDGJ >= KIKDATETOJUL(KIKE1JULTODATE(FISCALPERIODSTART(14,1)) - 90) and GLDGJ <= KIKDATETOJUL(KIKE1JULTODATE(FISCALPERIODEND(14,12)) + 90) AND GLOBJ IN ('5025','5026') AND GLLT ='AA' AND GLEXTL <> 'AM' AND GLEXR <> ' ' and GLRE = ' '
GROUP BY GL.GLEXR, GL.GLDCT,
CASE WHEN SDDCTO IN ('ST','SJ') THEN CAST(SDSHAN AS NCHAR(12)) ELSE TRIM(SDMCU) END, DTL.SDASN, DTL.SDDOC, DTL.SDDOCO, DTL.SDDCTO, DTL.SDSOQS, DTL.AER_SDSOQS, DTL.MDJ_SDSOQS, DTL.SDSHAN, DTL.SDAN8, SDURRF, GL.GLSUB, Weight, FG_Weight, AER_WEIGHT, MDJ_WEIGHT, MDJ_3rdParty_WEIGHT
We where provided with the below code to run ahead of the select statement which changes the way the Oracle DB optimizes the query.
alter session set optimizer_index_caching=0;
alter session set optimizer_index_cost_adj=80;
This fixed the issue.

Concatenating multiple CASE statements into one alias

After some previous help on how to approach a problem I am having with some legacy code, it seems like the best approach for my issue is to concatenate case statements to return a value I can parse out in PHP.
I am trying to do something like this, but it is returning many rows, and eventually getting this error:
Maximum stored procedure, function, trigger, or view nesting level
exceeded (limit 32).
SELECT org.org_id,
org.org_name_1,
Datename(YEAR, member.enroll_date) AS enroll_year,
Max(CASE
WHEN board.member_from IS NULL THEN 0
ELSE 1
END) AS board_member,
CASE
WHEN ( org.delete_reason = 'OUT'
AND org.org_delete_flag = 'Y'
AND org.org_status_flag = 'C' ) THEN 'out_of_business|'
ELSE ''
END + CASE
WHEN ( stat.carrier = 'BS'
AND stat.status_id IS NOT NULL
AND stat.termination_date IS NULL
AND stat.flat_dues > 0 ) THEN 'insurance_member|'
ELSE ''
END + CASE
WHEN ( stat.carrier = 'BS'
AND stat.status_id IS NOT NULL
AND stat.termination_date IS NULL
AND stat.flat_dues = 0
AND member.status_flag IN( 'C', 'P' ) ) THEN 'insurance_product|'
ELSE ''
END + CASE
WHEN ( member.enroll_date IS NOT NULL
AND member.status_flag NOT IN( 'C', 'P' ) ) THEN 'member_since|'
ELSE ''
END + CASE
WHEN ( org.org_relationship_parent = 'Y'
AND org.dues_category = 'MBR'
AND org.org_status_flag = 'R' ) THEN 'subsidiary_member|'
ELSE ''
END + CASE
WHEN ( org.org_misc_data_9 = 'PAC' ) THEN 'pac|'
ELSE ''
END + CASE
WHEN ( org.dues_category = 'PART' ) THEN 'partner_member|'
ELSE ''
END + CASE
WHEN ( org.dues_category = 'FREE'
AND org.org_status_flag = 'P' ) THEN 'associate_member|'
ELSE ''
END
--ELSE 'non_member'
--END
AS org_status,
60 AS expires_in,
CASE
WHEN stat.dues_type = 'M' THEN
CASE
WHEN ( stat.termination_date IS NULL ) THEN ( stat.flat_dues )
ELSE 0
END
ELSE
CASE
WHEN ( member.payments = 0 ) THEN member.dues_billed_annual
ELSE member.payments
END
END AS dues_level,
CASE
WHEN ( org.affiliate_code = 'PCCE'
AND org.dues_category = 'MBR'
AND org.org_status_flag = 'R' ) THEN 1
ELSE 0
END AS pcce_membr,
-- '$'+CONVERT(VARCHAR,#dues) AS dues_level,
Ltrim(#product_level) AS product_level,
Ltrim(#involve_level) AS involvement_level
FROM organiz AS org
LEFT JOIN affilbil AS member
ON member.status_id = org.org_id
AND member.dues_category = 'MBR'
LEFT JOIN individu AS ind
ON ind.org_id = org.org_id
LEFT JOIN commembr AS board
ON board.status_id = ind.ind_id
AND board.committee_code = '5'
AND board.member_to IS NULL
LEFT JOIN statinsmorn AS stat
ON stat.status_id = org.org_id
AND stat.carrier = 'BS'
AND stat.planz = 'PCI'
WHERE org.org_id = #org_id
GROUP BY org.org_id,
org.org_name_1,
member.enroll_date,
org.delete_reason,
org.org_status_flag,
org.org_delete_flag,
stat.status_id,
stat.flat_dues,
stat.dues_type,
stat.termination_date,
org.org_misc_data_9,
org_relationship_parent,
org.dues_category,
member.status_flag,
member.dues_billed_annual,
member.payments,
stat.carrier,
org.Affiliate_Code
Well, this is embarrassing.
When I was making my changes to the stored procedure, I had inadvertently placed a call to the same procedure at the bottom. So I was recursively calling the same procedure over and over again. DOH.