Nested case query Db2 - db2

I am trying to create a nested case statement in DB2. It's throwing me an error.
select tmp.claim_number,
SUM(tmp.LUMP_SUM_E) as LUMP_SUM_E
from (
select c.claim_number,
p.amount,
p.effective_gross_amt,
--p.lump_sum_e,
p.released,
p.to,
p.payment_option,
p.sub_benefit_type,
p.PAYMENT_FIELD,
CASE WHEN ((EXTRACT(YEAR FROM p.to) < EXTRACT(YEAR FROM p.released))
THEN
CASE WHEN (p.to <= '2020-07-01' and p.amount > 0)
THEN amount ELSE 0
END
END AS lump_sum_e
from CLAIMS.claim c inner join claims.payment p on c.id = p.claim_id and c.claim_Number IN (75248)
AND (
(p.RELEASED >= '2020-07-01' AND p.RELEASED <= '2021-06-30')
OR
(p.ATO_RELEASE_DATE >= '2020-07-01' AND p.ATO_RELEASE_DATE <= '2021-06-30')
)
) tmp
GROUP by tmp.claim_number;
it's throwing
1) [Code: -104, SQL State: 42601] An unexpected token "THEN" was found following "FROM p.released))
". Expected tokens may include: ")".. SQLCODE=-104, SQLSTATE=42601, DRIVER=4.22.29
2) [Code: -727, SQL State: 56098] An error occurred during implicit system action type "2". Information returned for the error includes SQLCODE "-104", SQLSTATE "42601" and message tokens "THEN|FROM p.released))
|)".. SQLCODE=-727, SQLSTATE=56098, DRIVER=4.22.29
Any idea how to write a nested case statement in Db2 please?.
Regards,
R

You need to fix your query syntax.
select tmp.claim_number,
SUM(tmp.LUMP_SUM_E) as LUMP_SUM_E
from (select c.claim_number,
p.amount,
p.effective_gross_amt,
--p.lump_sum_e,
p.released,
p.to,
p.payment_option,
p.sub_benefit_type,
p.PAYMENT_FIELD,
CASE WHEN (EXTRACT(YEAR FROM p.to) < EXTRACT(YEAR FROM p.released))
THEN
CASE WHEN (p.to <= '2020-07-01' and p.amount > 0)
THEN amount ELSE 0
END
END AS lump_sum_e
from CLAIMS.claim c
inner join claims.payment p on c.id = p.claim_id
and c.claim_Number IN (75248)
AND (
(p.RELEASED >= '2020-07-01'
AND p.RELEASED <= '2021-06-30')
OR
(p.ATO_RELEASE_DATE >= '2020-07-01'
AND p.ATO_RELEASE_DATE <= '2021-06-30')
)
) tmp
GROUP by tmp.claim_number;

Consider using explicit parenthesis around the inner CASE expression. Also make sure that the ( and ) are in sync. Based on the syntax for the CASE statement it should work.

Related

Not In use with group by in oracle Sql developer

SELECT A.SALE_ID,COUNT(A.SALE_ID) AS TOTAL_PENDING,C.ALLOTTE,C.FORM_NO,E.CUS_NAME
FROM B_UNIT_BOOKING_DETAIL A
JOIN COD_BOOKING_MASTER C ON A.SALE_ID=C.SALE_ID
JOIN COD_FORM_REG D ON C.FORM_NO=D.FORM_NO
JOIN COD_CUSTOMER_MASTER E ON E.CUS_ID=C.ALLOTTE
WHERE A.DUE_DATE < '20-AUG-21' AND A.RECEIVED='N' AND
(SELECT COUNT(B.SALE_ID) FROM B_UNIT_BOOKING_DETAIL B
WHERE B.DUE_DATE < '20-AUG-21' AND B.RECEIVED='N'
AND B.SALE_ID=A.SALE_ID GROUP BY B.SALE_ID ) > '2'
AND E.PROJECT_ID='4'
AND E.COMPANY_ID='2' AND C.FORM_NO NOT IN (SELECT REG_NO FROM COD_RECOVERY_RECORD) AND ROWNUM <= 50
GROUP BY A.SALE_ID ,C.ALLOTTE,C.FORM_NO,D.CUS_ID,E.CUS_NAME
This query shows the error invalid number but I check all the field every datatype is correct by still its showing error can anyone please tell me how I can do this.
SELECT A.SALE_ID,COUNT(A.SALE_ID) AS TOTAL_PENDING,C.ALLOTTE,C.FORM_NO,E.CUS_NAME
FROM B_UNIT_BOOKING_DETAIL A
JOIN COD_BOOKING_MASTER C ON A.SALE_ID=C.SALE_ID
JOIN COD_FORM_REG D ON C.FORM_NO=D.FORM_NO
JOIN COD_CUSTOMER_MASTER E ON E.CUS_ID=C.ALLOTTE
WHERE A.DUE_DATE < '20-AUG-21' AND A.RECEIVED='N' AND
(SELECT COUNT(B.SALE_ID) FROM B_UNIT_BOOKING_DETAIL B
WHERE B.DUE_DATE < '20-AUG-21' AND B.RECEIVED='N'
AND B.SALE_ID=A.SALE_ID GROUP BY B.SALE_ID ) > '2'
AND E.PROJECT_ID='4'
AND E.COMPANY_ID='2' AND D.FORM_NO NOT IN (SELECT REG_NO FROM COD_RECOVERY_RECORD) AND ROWNUM <= 50
GROUP BY A.SALE_ID ,C.ALLOTTE,C.FORM_NO,D.CUS_ID,E.CUS_NAME
I just change ALLASES OF FORM_NO TO GET BTHE RESULT.

I've been running this code monthly for over a year, but for some reason am just now getting this SQL group by/aggregate error

I've run this code regularly for awhile without any error, but am suddenly seeing this error:
Msg 8120, Level 16, State 1, Line 95
Column '#CampaignHistory.MaturityDate' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause.
Msg 8120, Level 16, State 1, Line 96
Column '#CampaignHistory.MaturityDate' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause.
Here's the code I'm using. Everything above this code runs fine w/o errors:
SELECT CASE WHEN MaturityDate <= '2021-01-31' THEN 'Closed'
WHEN MaturityDate >= '2021-02-01' THEN 'Active' END AS Campaign,
COUNT (DISTINCT CustomerID) AS Peeps
FROM #CampaignHistory
GROUP BY CASE WHEN MaturityDate <= '2020-01-31' THEN 'Closed'
WHEN MaturityDate >= '2021-02-01' THEN 'Active' END;
The expressions in the SELECT clause and the GROUP BY clause are different: the first one mentions 2021-01-31, the second one mentions 2020-01-31.
To avoid duplicating the code and to prevent such typos, you can use one of the following queries:
SELECT Campaign, COUNT(DISTINCT CustomerID) AS Peeps
FROM (
SELECT CustomerID,
CASE
WHEN MaturityDate <= '2021-01-31' THEN 'Closed'
WHEN MaturityDate >= '2021-02-01' THEN 'Active'
END AS Campaign
FROM #CampaignHistory
) x GROUP BY Campaign
or
SELECT Campaign, COUNT(DISTINCT CustomerID) AS Peeps
FROM #CampaignHistory
CROSS APPLY (
SELECT CASE
WHEN MaturityDate <= '2021-01-31' THEN 'Closed'
WHEN MaturityDate >= '2021-02-01' THEN 'Active'
END AS Campaign
) x
GROUP BY x.Campaign

Receiving error when converting text to date in Redshift

I am running a query that Redshift is throwing an error on "SQL Error [500310][57014]:Amazon Invalid operation: Error converting text to date;"
However, when I remove the Joined tables, or remove the conversions from the WHERE clause, it no longer throws an error. Thus I suspect something else is going on and this error is misleading.
I have looked at the data and it none of the dates look strange or out of range.
Here is the query that throws an error:
SELECT m.member_id,
t.tracker_id,
DATE(ma.yyyymmdd) AS tracked_date,
DATE(ma.updated_date) AS updated_date
FROM import_genesis.member_activities ma
INNER JOIN master."member" m
ON ma.memberid = m.member_legacy_id
INNER JOIN master.action_activity aa
ON ma.activity_type = aa.activity_type
INNER JOIN master.tracker t
ON t.action_id = aa.action_id
WHERE DATE(ma.yyyymmdd) > DATE(DATEADD(DAY, -14, GETDATE()))
AND DATE(ma.yyyymmdd) <= GETDATE();
Here are two queries that do NOT throw an error:
SELECT DATE(ma.yyyymmdd) AS tracked_date,
DATE(ma.updated_date) AS updated_date
FROM import_genesis.member_activities ma
WHERE DATE(ma.yyyymmdd) > DATE(DATEADD(DAY, -14, GETDATE()))
AND DATE(ma.yyyymmdd) <= GETDATE();
SELECT m.member_id,
t.tracker_id,
DATE(ma.yyyymmdd) AS tracked_date,
DATE(ma.updated_date) AS updated_date
FROM import_genesis.member_activities ma
INNER JOIN master."member" m
ON ma.memberid = m.member_legacy_id
INNER JOIN master.action_activity aa
ON ma.activity_type = aa.activity_type
INNER JOIN master.tracker t
ON t.action_id = aa.action_id;
Any ideas as to what might be wrong or any potential workarounds?

Unexpected "Subquery returned more than 1 value"

Tables have this structure: groupTable > lineGroupJoinTable > linesTable (name are obfuscated names)
I have the following query which returns this error:
Subquery returned more than 1 value. This is not permitted when the
subquery follows =, !=, <, <= , >, >= or when the subquery is used as
an expression.
The thing is that I expect that since the subquery is group, I should not get this error. I'm probably missing something.
UPDATE dbo.groupTable
SET fieldToUpdate = CASE WHEN fieldToUpdate IS NULL THEN NULL ELSE
(
SELECT sumTable.fieldToSum FROM
dbo.groupTable gt
INNER JOIN
(
SELECT lgjt.groupdId1, lgjt.groupdId2, SUM(lt.fieldToSum) as fieldToSum
FROM lineGroupJoinTable lgjt
INNER JOIN linesTable lt
ON
lt.fieldToSum IS NOT NULL AND lt.fieldToSum > 0 AND
lgjt.lineId1 = lt.lineId1 AND lgjt.lineId2 = lt.lineId2
GROUP BY lgjt.groupdId1, lgjt.groupdId2
) sumTable
ON sumTable.groupdId1 = gt.groupdId1 AND sumTable.groupdId2 = gt.groupdId2
)
END
This variation was also try following a suggestion but return the same error:
UPDATE dbo.groupTable
SET fieldToUpdate = CASE WHEN fieldToUpdate IS NULL THEN NULL ELSE
(
SELECT SUM(sumTable.fieldToSum) FROM
dbo.groupTable gt
INNER JOIN
(
SELECT lgjt.groupdId1, lgjt.groupdId2, SUM(lt.fieldToSum) as fieldToSum
FROM lineGroupJoinTable lgjt
INNER JOIN linesTable lt
ON
lt.fieldToSum IS NOT NULL AND lt.fieldToSum > 0 AND
lgjt.lineId1 = lt.lineId1 AND lgjt.lineId2 = lt.lineId2
GROUP BY lgjt.groupdId1, lgjt.groupdId2
) sumTable
ON sumTable.groupdId1 = gt.groupdId1 AND sumTable.groupdId2 = gt.groupdId2
GROUP BY gt.groupdId1, gt.groupdId2
)
END
Probably because dbo.groupTable has multiple value for the combination id1 and id2. I suggest to group on the id1 and id2 column and do a SUM, that case you will have only 1 result.
UPDATE dbo.groupTable
SET fieldToUpdate = CASE WHEN fieldToUpdate IS NULL THEN NULL ELSE
(
SELECT SUM(sumTable.fieldToSum) FROM
dbo.groupTable gt
INNER JOIN
(
SELECT lgjt.id1, lgjt.id2, SUM(lt.fieldToSum) as fieldToSum
FROM lineGroupJoinTable lgjt
INNER JOIN linesTable lt
ON
lt.fieldToSum IS NOT NULL AND lt.fieldToSum > 0 AND
lgjt.id3 = lt.id3 AND lgjt.id4 = lt.id4
GROUP BY lgjt.id1, lgjt.id2
) sumTable
ON sumTable.id1 = gt.id1 AND sumTable.id2 = gt.id2
GROUP BY gt.id1, gt.id2
)
END

Replace Subselect for something more efficient

I have this query which takes a long time, partly because the number of records in the table excedd 500 000 records, but the join I have to use slows it down quite a lot, at least to my beliefs
SELECT TOP (10) PERCENT H1.DateCompteur, CASE WHEN (h1.cSortie - h2.cSortie > 0)
THEN h1.cSortie - h2.cSortie ELSE 0 END AS Compte, H1.IdMachine
FROM dbo.T_HistoriqueCompteur AS H1 INNER JOIN
dbo.T_HistoriqueCompteur AS H2 ON H1.IdMachine = H2.IdMachine AND H2.DateCompteur =
(SELECT MAX(DateCompteur) AS Expr1
FROM dbo.T_HistoriqueCompteur AS HS
WHERE (DateCompteur < H1.DateCompteur) AND (H1.IdMachine = IdMachine))
ORDER BY H1.DateCompteur DESC
The order by is important since I need only the most recent informations. I tried using the ID field in my sub select since they are ordred by date but could not detect any significant improvement.
SELECT TOP (10) PERCENT H1.DateCompteur, CASE WHEN (h1.cSortie - h2.cSortie > 0)
THEN h1.cSortie - h2.cSortie ELSE 0 END AS Compte, H1.IdMachine
FROM dbo.T_HistoriqueCompteur AS H1 INNER JOIN
dbo.T_HistoriqueCompteur AS H2 ON H1.IdMachine = H2.IdMachine AND H2.ID =
(SELECT MAX(ID) AS Expr1
FROM dbo.T_HistoriqueCompteur AS HS
WHERE (ID < H1.ID) AND (H1.IdMachine = IdMachine))
ORDER BY H1.DateCompteur DESC
the table I use look a little like this (I got much more columns but they are unused in this query).
ID bigint
IdMachine bigint
cSortie bigint
DateCompteur datetime
I think that if I could get rid of the sub select, my query would run much faster but I can't really find a way to do so. What I really want to do is to find the previous row with the same IdMachine so that I can calculate the difference between the two cSortie values. The case in the query is because something it's reseted to 0 and in this case, I want to return 0 instead of a negative value.
So my question is this : Can I do better than what I already have ??? I plan to put this in a view if that makes a difference.
Try this query
WITH T as
(
SELECT TOP (10) PERCENT H1.DateCompteur, H1.cSortie as cSortie1, H1.IdMachine,
(
SELECT TOP 1 H2.cSortie
FROM dbo.T_HistoriqueCompteur H2
WHERE (H2.DateCompteur < H1.DateCompteur) AND (H1.IdMachine = H2.IdMachine)
ORDER BY H2.DateCompteur DESC
) as cSortie2
FROM dbo.T_HistoriqueCompteur AS H1
ORDER BY H1.DateCompteur DESC
)
select DateCompteur,
CASE WHEN (cSortie1 - cSortie2 > 0)
THEN cSortie1 - cSortie2
ELSE 0 END
AS Compte,
IdMachine
FROM T
You could also try CTE's (common table expressions) with windowing functions (ROW_NUMBER):
;WITH CTE AS
(
SELECT ID,IdMachine,cSortie,ROW_NUMBER() OVER(PARTITION BY h.IdMachine ORDER BY ID ASC) AS [ROW]
FROM T_HistoriqueCompteur h
)
SELECT
TOP (10) PERCENT
H1.DateCompteur,
CASE WHEN (h1.cSortie - h2.cSortie > 0) THEN h1.cSortie - h2.cSortie
ELSE 0
END AS Compte,
H1.IdMachine
FROM dbo.T_HistoriqueCompteur AS H1
INNER JOIN CTE cte on cte.idmachine = h1.idmachine and cte.id = h1.id
INNER JOIN CTE h2 on h2.idmachine = cte.idmachine and h2.row + 1 = cte.row
ORDER BY H1.DateCompteur DESC