PostgreSQL how to group by rows by primary key? - sql

i have following query
SELECT "Nomenclature",
CASE
WHEN ad."Title" = 'Кухня'
THEN au."Value"
ELSE NULL END AS "Кухня",
CASE
WHEN ad."Title" = 'Вегетарианское'
THEN au."Value"
ELSE NULL END AS "Вегетарианское",
CASE
WHEN ad."Title" = 'Постное' THEN au."Value"
ELSE NULL END AS "Постное",
CASE
WHEN ad."Title" = 'Постное'
THEN au."Value"
ELSE NULL END AS "Для ресторанов"
FROM "AttributeUnit" au
JOIN "AttributeDictionary" ad ON au."AttributeDictionary" = ad."#AttributeDictionary"
WHERE "Nomenclature" = ANY (ARRAY(SELECT "#Nomenclature" FROM base_info))
AND ad."Title" IN ('Кухня', 'Вегетарианское', 'Постное', 'Для ресторанов')
In the result i have 3 columns with same primary key.
How to group by the result that it will looks like
Nomenclature.
Кухня
Вегетерианское
Постное
Для ресторанов
8677
Италия
True

I'm guessing you want aggregation:
SELECT "Nomenclature",
MAX(CASE WHEN ad."Title" = 'Кухня' THEN au."Value" END) AS "Кухня",
MAX(CASE WHEN ad."Title" = 'Вегетарианское' THEN au."Value" END) AS "Вегетарианское",
MAX(CASE WHEN ad."Title" = 'Постное' THEN au."Value" END) AS "Постное",
MAX(CASE WHEN ad."Title" = 'Постное' THEN au."Value" END) AS "Для ресторанов"
FROM "AttributeUnit" au JOIN
"AttributeDictionary" ad
ON au."AttributeDictionary" = ad."#AttributeDictionary"
WHERE "Nomenclature" = ANY (ARRAY(SELECT "#Nomenclature" FROM base_info)) AND
ad."Title" IN ('Кухня', 'Вегетарианское', 'Постное', 'Для ресторанов')
GROUP BY "Nomenclature";

Related

How to do a Sum(case when) using JPA

I don't have much background in converting between SQL and JPA-like code so I was wondering how I would go about converting the following to JPA syntax? Or if it's even possible? Thanks in advance.
SELECT DLR_CD, COUNT(*),
SUM(CASE WHEN CMPLT_DT='0001-01-01' THEN 1 END),
SUM(CASE WHEN CMPLT_DT!='0001-01-01' THEN 1 END),
SUM(CASE WHEN YEAR(CMPLT_DT) = YEAR(CURRENT DATE)-1 THEN 1 END),
SUM(CASE WHEN YEAR(CMPLT_DT) = YEAR(CURRENT DATE) THEN 1 END),
SUM(CASE WHEN (CMPLT_DT IS NULL OR CMPLT_DT='0001-01-01') THEN A.RPR_LBR_HR ELSE 0 END)
FROM <db2 table 1> A
join <db2 table 2> B
on ANUN_IND='A'
AND B.PIP_PSP_NO=A.PIP_PSP_NO
--OPTIONAL PARAMS GO HERE
GROUP BY DLR_CD
FOR FETCH ONLY WITH UR;
Edit: updated with full, barely-modified query.
Using criteria api it would look something like this:
CriteriaBuilder cb = entityManager.getCriteriaBuilder();
CriteriaQuery<YourPojo> cq = cb.createQuery(YourPojo.class);
Root<Entity1> root = cq.from(Entity1.class);
Join<Entity1,Entity2> join = root.join(Entity1_.entity2,JoinType.LEFT);
/*
* the join by ID is implicit when using the .join method, the second
* condition is added as follows (Since you don't indicate the alias,
* I assume it is a field from table 2):
*/
join.on(cb.equal(join.get(Entity2_.anunInd),'A'));
Calendar dayOne = Calendar.getInstance();
dayOne.set(1, 0, 1);
//Expression for first and second sum case
Expression<Long> caseDate = cb.<Long>selectCase().when(cb.equal(root.get(Entity1_.cmpltDt),dayOne.getTime()), 1L).otherwise(0L);
Expression<Long> sumDate = cb.sum(caseDate);
//Expression for third sum case
Expression<Long> caseDateWithYearM1 = cb.<Long>selectCase().when(
cb.equal(cb.function("YEAR", Long.class, root.get(Entity1_.cmpltDt)),
cb.sum(cb.function("YEAR", Long.class, cb.literal(new Date())),-1))
, 1L).otherwise(0L);
Expression<Long> sumDateWithYearM1 = cb.sum(caseDateWithYearM1);
//Expression for fourth sun case
Expression<Long> caseDateWithYear = cb.<Long>selectCase().when(
cb.equal(cb.function("YEAR", Long.class, root.get(Entity1_.cmpltDt)),
cb.function("YEAR", Long.class, cb.literal(new Date())))
, 1L).otherwise(0L);
Expression<Long> sumDateWithYear = cb.sum(caseDateWithYear);
Expression<Long> caseNew = cb.<Long>selectCase().when(cb.or(
cb.equal(root.get(Entity1_.cmpltDt),dayOne.getTime()),
cb.equal(root.get(Entity1_.cmpltDt),dayOne.getTime())),
root.get(Entity1_.rprLbrHr)).otherwise(0L);
Expression<Long> sumNew = cb.sum(caseNew);
cq.multiselect(
root.get(Entity1_.dlrCd),
cb.count(root.get(Entity1_.dlrCd)),
sumDate,
sumDate,
sumDateWithYearM1,
sumDateWithYear,
sumNew
);
cq.groupBy(root.get(Entity1_.dlrCd));
List<YourPojo> resultado = entityManager.createQuery(cq).getResultList();
Your Pojo has to have a constructor with the same parameters (order and type) as the multiselect method.
The result query:
select
entity1.DLR_CD as col_0_0_,
count(entity1.DLR_CD) as col_1_0_,
sum(case when entity1.CMPLT_DT=? then 1 else 0
end) as col_2_0_,
sum(case when entity1.CMPLT_DT=? then 1 else 0
end) as col_3_0_,
sum(case when extract(year from entity1.CMPLT_DT)=extract(year from ?)+-1 then 1 else 0
end) as col_4_0_,
sum(case when extract(year from entity1.CMPLT_DT)=extract(year from ?) then 1 else 0
end) as col_5_0_ ,
sum(case when entity1.CMPLT_DT is null or entity1.CMPLT_DT=? then entity1.RPR_LBR_HR else 0
end) as col_6_0_,
from
entity1
left join
entity2 on entity1.PIP_PSP_NO = entity2.PIP_PSP_NO and
entity2.ANUN_IND='A'
group by
entity1.DLR_CD

How do I replace null with 0 in SUM CASE WHEN statement?

I am using a CASE WHEN statement and a SUM function. I want to replace all nulls with 0.
I tried adding a 0 at the end of my statement.
This is my current code
select ID, PT_Number,
ORGANIZATION,
[Approved] = sum(case when PT_TYPE = 'Lend' then Approved END),
[Disbursed] = sum(case when PT_TYPE = 'Give' then Disbursed end),
[Repaid] = sum(case when PT_TYPE = 'Pay' then Payment end)
from TABLE1
group by ID, PT_Number,
ORGANIZATION
This is what I am trying
[Approved] = sum(case when PT_TYPE = 'Lend' then Approved END, 0),
[Disbursed] = sum(case when PT_TYPE = 'Give' then Disbursed end, 0),
[Repaid] = sum(case when PT_TYPE = 'Pay' then Payment end, 0)
Just add an else clause:
select ID, PT_Number,
ORGANIZATION,
[Approved] = sum(case when PT_TYPE = 'Lend' then Approved else 0 END),
[Disbursed] = sum(case when PT_TYPE = 'Give' then Disbursed else 0 end),
[Repaid] = sum(case when PT_TYPE = 'Pay' then Payment else 0 end)
from TABLE1
group by ID, PT_Number, ORGANIZATION;
You could also use coalesce() but that seems like overkill.

ERROR! - Cannot use an aggregate or a subquery in an expression used for the group by list of a GROUP BY clause

I'm getting this error: Cannot use an aggregate or a subquery in an expression used for the group by list of a GROUP BY clause.
I've looked around but I can not find anything to help me in my case.
I am using SQL Server 2012
SELECT DISTINCT
CommodityCode.CommodityCode AS ComCode,
Facility.FacilityAcctNum,
Vessel.VesselType,
Facility.FacilityNm,
Case
When Commodities.ShippedReceivedId = 'R' And Commodities.ForeignDomesticId = 'F' Then
Case When Commodities.Amount Is Null Or Commodities.Unit Is Null Then Null
Else
Round (Commodities.Amount/Case When Commodities.Unit = 'B' Then (Select BushelFactor From CommodityCode
Where CommodityCode.CommodityCode = Commodities.CommodityCode)
Else (Select ShortTonFactor From Unit
Where Unit.Unit = Commodities.Unit) End,2
)
End
Else 0
End AS RecF,
Case
When Commodities.ShippedReceivedId = 'R' And Commodities.ForeignDomesticId = 'D' Then
Case When Commodities.Amount Is Null Or Commodities.Unit Is Null Then Null
Else
Round (Commodities.Amount/Case When Commodities.Unit = 'B' Then (Select BushelFactor From CommodityCode
Where CommodityCode.CommodityCode = Commodities.CommodityCode)
Else (Select ShortTonFactor From Unit
Where Unit.Unit = Commodities.Unit) End,2
)
End
Else 0
End AS RecD,
Case
When Commodities.ShippedReceivedId = 'S' And Commodities.ForeignDomesticId = 'D' Then
Case When Commodities.Amount Is Null Or Commodities.Unit Is Null Then Null
Else
Round (Commodities.Amount/Case When Commodities.Unit = 'B' Then (Select BushelFactor From CommodityCode
Where CommodityCode.CommodityCode = Commodities.CommodityCode)
Else (Select ShortTonFactor From Unit
Where Unit.Unit = Commodities.Unit) End,2
)
End
Else 0
End AS Shipped,
Case
When Commodities.ShippedReceivedId = 'S' And Commodities.ForeignDomesticId = 'F' Then
Case When Commodities.Amount Is Null Or Commodities.Unit Is Null Then Null
Else
Round (Commodities.Amount/Case When Commodities.Unit = 'B' Then (Select BushelFactor From CommodityCode
Where CommodityCode.CommodityCode = Commodities.CommodityCode)
Else (Select ShortTonFactor From Unit
Where Unit.Unit = Commodities.Unit) End,2
)
End
Else 0
End AS ShippedF,
Commodities.Destination,
Commodities.Origin,
Commodities.Specific,
CommodityCode.Descr,
Facility.FacilityID,
TransactionCharge.ArrivalDt,
TransactionCharge.DepartDt,
TransactionCharge.DtDocked,
TransactionCharge.DtSailed
FROM Vessel
INNER JOIN Commodities
INNER JOIN CommodityCode ON Commodities.CommodityCode = CommodityCode.CommodityCode
INNER JOIN TransactionCharge ON Commodities.TransactionID = TransactionCharge.TransactionID ON Vessel.VesselID = TransactionCharge.VesselId
INNER JOIN Facility ON TransactionCharge.FacilityID = Facility.FacilityID
INNER JOIN Unit ON Commodities.Unit = Unit.Unit
INNER JOIN TransactionFee ON TransactionCharge.TransactionID = TransactionFee.TransactionID
GROUP BY
CommodityCode.CommodityCode,
Facility.FacilityAcctNum,
Vessel.VesselType,
Facility.FacilityNm,
Commodities.Destination,
Commodities.Origin,
Commodities.Specific,
CommodityCode.Descr,
Facility.FacilityID,
Case
When Commodities.ShippedReceivedId = 'R' And Commodities.ForeignDomesticId = 'F' Then
Case When Commodities.Amount Is Null Or Commodities.Unit Is Null Then Null
Else
Round (Commodities.Amount/Case When Commodities.Unit = 'B' Then (Select BushelFactor From CommodityCode
Where CommodityCode.CommodityCode = Commodities.CommodityCode)
Else (Select ShortTonFactor From Unit
Where Unit.Unit = Commodities.Unit) End,2
)
End
Else 0
End,
Case
When Commodities.ShippedReceivedId = 'R' And Commodities.ForeignDomesticId = 'D' Then
Case When Commodities.Amount Is Null Or Commodities.Unit Is Null Then Null
Else
Round (Commodities.Amount/Case When Commodities.Unit = 'B' Then (Select BushelFactor From CommodityCode
Where CommodityCode.CommodityCode = Commodities.CommodityCode)
Else (Select ShortTonFactor From Unit
Where Unit.Unit = Commodities.Unit) End,2
)
End
Else 0
End,
Case
When Commodities.ShippedReceivedId = 'S' And Commodities.ForeignDomesticId = 'D' Then
Case When Commodities.Amount Is Null Or Commodities.Unit Is Null Then Null
Else
Round (Commodities.Amount/Case When Commodities.Unit = 'B' Then (Select BushelFactor From CommodityCode
Where CommodityCode.CommodityCode = Commodities.CommodityCode)
Else (Select ShortTonFactor From Unit
Where Unit.Unit = Commodities.Unit) End,2
)
End
Else 0
End,
Case
When Commodities.ShippedReceivedId = 'S' And Commodities.ForeignDomesticId = 'F' Then
Case When Commodities.Amount Is Null Or Commodities.Unit Is Null Then Null
Else
Round (Commodities.Amount/Case When Commodities.Unit = 'B' Then (Select BushelFactor From CommodityCode
Where CommodityCode.CommodityCode = Commodities.CommodityCode)
Else (Select ShortTonFactor From Unit
Where Unit.Unit = Commodities.Unit) End,2
)
End
Else 0
End,
TransactionCharge.ArrivalDt,
TransactionCharge.DepartDt,
TransactionCharge.DtDocked,
TransactionCharge.DtSailed
HAVING (Vessel.VesselType='V' Or Vessel.VesselType='O')
You have subqueries in your case statement in your GROUP BY. For example, looking at the first part of the case statement:
When Commodities.ShippedReceivedId = 'R' And Commodities.ForeignDomesticId = 'F' Then
Case When Commodities.Amount Is Null Or Commodities.Unit Is Null Then Null
Else
Round (Commodities.Amount/Case When Commodities.Unit = 'B' Then (Select BushelFactor From CommodityCode
Where CommodityCode.CommodityCode = Commodities.CommodityCode)
Else (Select ShortTonFactor From Unit
Where Unit.Unit = Commodities.Unit) End,2
)
End
Else 0
End,
There are two there to start with, beginning with Select BushelFactor... and Select ShortTonFactor..., so you will have to remove them.
I had a quick go at reformatting your query and removing/ commenting some of the issues with it:
SELECT --DISTINCT - do you really want DISTINCT?
cc.CommodityCode AS ComCode,
f.FacilityAcctNum,
v.VesselType,
f.FacilityNm,
CASE
WHEN Commodities.ShippedReceivedId = 'R' AND Commodities.ForeignDomesticId = 'F' THEN
CASE
WHEN Commodities.Amount IS NULL OR Commodities.Unit IS NULL THEN NULL
ELSE ROUND(Commodities.Amount /
CASE
WHEN Commodities.Unit = 'B' THEN cc.BushelFactor
ELSE u.ShortTonFactor
END, 2)
END
ELSE 0
END AS RecF,
CASE
WHEN Commodities.ShippedReceivedId = 'R' AND Commodities.ForeignDomesticId = 'D' THEN
CASE
WHEN Commodities.Amount IS NULL OR Commodities.Unit IS NULL THEN NULL
ELSE
ROUND(Commodities.Amount /
CASE
WHEN Commodities.Unit = 'B' THEN cc.BushelFactor
ELSE u.ShortTonFactor END, 2)
END
ELSE 0
END AS RecD,
CASE
WHEN Commodities.ShippedReceivedId = 'S' AND Commodities.ForeignDomesticId = 'D' THEN
CASE
WHEN Commodities.Amount IS NULL OR Commodities.Unit IS NULL THEN NULL
ELSE
ROUND(Commodities.Amount /
CASE
WHEN Commodities.Unit = 'B' THEN cc.BushelFactor
ELSE u.ShortTonFactor
END, 2)
END
ELSE 0
END AS Shipped,
CASE
WHEN Commodities.ShippedReceivedId = 'S' AND Commodities.ForeignDomesticId = 'F' THEN
CASE
WHEN Commodities.Amount IS NULL OR Commodities.Unit IS NULL THEN NULL
ELSE
ROUND(Commodities.Amount/
CASE
WHEN Commodities.Unit = 'B' THEN cc.BushelFactor
ELSE u.ShortTonFactor
END, 2)
END
ELSE 0
END AS ShippedF,
c.Destination,
c.Origin,
c.Specific,
cc.Descr,
f.FacilityID,
tc.ArrivalDt,
tc.DepartDt,
tc.DtDocked,
tc.DtSailed
FROM
Vessel v
INNER JOIN Commodities c ON --some_condtion, OR is this a cross join?
INNER JOIN CommodityCode cc ON c.CommodityCode = cc.CommodityCode
INNER JOIN TransactionCharge tc ON c.TransactionID = tc.TransactionID AND v.VesselID = tc.VesselId
INNER JOIN Facility f ON tc.FacilityID = f.FacilityID
INNER JOIN Unit u ON c.Unit = u.Unit
INNER JOIN TransactionFee td ON tc.TransactionID = tf.TransactionID
WHERE
v.VesselType IN ('V', 'O');
I don't expect this to produce the answers you want, but it might make it easier to spot what is wrong with your original query now that the logic is somewhat simplified?

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.

Using case to choose between two sentences in where clause (Oracle)

im creating a function and i need to choose between two sentences depending on a parameter's value (PTIPO)
Below is my code
SELECT SUM(
CASE PTIPO
WHEN 0 THEN (CASE WHEN (A.NT = 0) THEN A.VALOR ELSE 0 END)
WHEN 1 THEN (CASE WHEN (A.NT = 1) THEN A.VALOR ELSE 0 END)
WHEN 2 THEN (CASE WHEN (A.NT = 1) THEN A.VALOR ELSE -A.VALOR END)
END)
INTO nresp
FROM mov_caja a
JOIN enc_movp b ON a.docid = b.docid
JOIN c_caja c ON a.cajaid = c.cajaid
WHERE c.cajaid = pcajaid AND(
CASE WHEN(PTIPO = 2) --this is what causes the issue.
THEN
b.cod_compro = ncompini OR (b.fecha_mov BETWEEN pfecha_ini AND pfecha_fin)
ELSE
b.cod_compro != ncompini AND b.fecha_mov BETWEEN pfecha_ini AND pfecha_fin
END);
The error is "missing keyword", but i know the problem is the last CASE.
How else could i select between the sentences. Is the case a proper way or should i use another statement ?
A case can return a value, but not an expression. This should do the trick, although I feel it could even be simpler:
SELECT SUM(
CASE PTIPO
WHEN 0 THEN (CASE WHEN (A.NT = 0) THEN A.VALOR ELSE 0 END)
WHEN 1 THEN (CASE WHEN (A.NT = 1) THEN A.VALOR ELSE 0 END)
WHEN 2 THEN (CASE WHEN (A.NT = 1) THEN A.VALOR ELSE -A.VALOR END)
END)
INTO nresp
FROM mov_caja a
JOIN enc_movp b ON a.docid = b.docid
JOIN c_caja c ON a.cajaid = c.cajaid
WHERE
c.cajaid = pcajaid AND
(
(PTIPO = 2 and (b.cod_compro = ncompini OR b.fecha_mov BETWEEN pfecha_ini AND pfecha_fin))
OR
(PTIPO <> 2 and (b.cod_compro != ncompini AND b.fecha_mov BETWEEN pfecha_ini AND pfecha_fin))
)
Try this:
WHERE c.cajaid = pcajaid AND
(
PTIPO = 2
AND (
b.cod_compro = ncompini
OR b.fecha_mov BETWEEN pfecha_ini AND pfecha_fin
)
OR
PTIPO != 2
AND (
b.cod_compro != ncompini
AND b.fecha_mov BETWEEN pfecha_ini AND pfecha_fin
)
)