Use Case Statement in Join - sql

Hi every one i want to use case statement in join using this query and got error
Select CONVERT(VARCHAR(10), SII.SIDATE,103)DATE,SII.SALEID,SII.ItemName,SI.TenancyID
FROM F_SALESINVOICEITEM SII
INNER JOIN F_SALESINVOICE SI ON SI.SALEID=SII.SALEID
INNER JOIN #TempTableSearch ts ON CASE
WHEN ts.ACCOUNTTYPE = '1' THEN ts.ACCOUNTID=SI.TENANCYID
WHEN ts.ACCOUNTTYPE='2' THEN ts.ACCOUNTID=SI.EMPLOYEEID
WHEN ts.ACCOUNTTYPE='3' THEN ts.ACCOUNTID=SI.SUPPLIERID
WHEN ts.ACCOUNTTYPE='4' THEN ts.ACCOUNTID=SI.SALESCUSTOMERID
Error
Incorrect syntax near '='.
Please help me to solve this error.

IT should be,
ON
ts.ACCOUNTID = CASE
WHEN ts.ACCOUNTTYPE = '1' THEN SI.TENANCYID
WHEN ts.ACCOUNTTYPE = '2' THEN SI.EMPLOYEEID
WHEN ts.ACCOUNTTYPE = '3' THEN SI.SUPPLIERID
WHEN ts.ACCOUNTTYPE = '4' THEN SI.SALESCUSTOMERID
END

Instead of using CASE, I'd much rather do this:
Select CONVERT(VARCHAR(10), SII.SIDATE,103)DATE,SII.SALEID,SII.ItemName,SI.TenancyID
FROM F_SALESINVOICEITEM SII
INNER JOIN F_SALESINVOICE SI ON SI.SALEID=SII.SALEID
INNER JOIN #TempTableSearch ts ON
(ts.ACCOUNTTYPE='1' AND ts.ACCOUNTID=SI.TENANCYID)
OR (ts.ACCOUNTTYPE='2' AND ts.ACCOUNTID=SI.EMPLOYEEID)
OR (ts.ACCOUNTTYPE='3' AND ts.ACCOUNTID=SI.SUPPLIERID)
OR (ts.ACCOUNTTYPE='4' AND ts.ACCOUNTID=SI.SALESCUSTOMERID)
To explain why the query didn't work for you: the syntax of the CASE requires an END at the end of the clause. It would work, as the other solutions proposed suggest, but I find this version to be more convenient to understand - although this part is highly subjective.

you can do this, so you have no chance to misspell something (note that ACCOUNTTYPE and ACCOUNTID used only when needed, you don't have to copy-paste it)
select
convert(varchar(10), SII.SIDATE,103) as DATE,
SII.SALEID, SII.ItemName, SI.TenancyID
from F_SALESINVOICEITEM as SII
inner join F_SALESINVOICE as SI on SI.SALEID = SII.SALEID
outer apply (
'1', SI.TENANCYID
'2', SI.EMPLOYEEID
'3', SI.SUPPLIERID
'4', SI.SALESCUSTOMERID
) as C(ACCOUNTTYPE, ACCOUNTID)
inner join #TempTableSearch as ts on
ts.ACCOUNTTYPE = C.ACCOUNTTYPE and ts.ACCOUNTID = C.ACCOUNTID

You have syntax error. You are missing END there.

You must understand that CASE ... END block is NOT equivalent to IF { } from C-like languages. Much rather this is equivalent to elaborate version of ... ? ... : ... operator from C-like languages. What it means that the WHOLE CASE block must essentially evaluate to single value and that this value has to be the same type no matter which case of the block is executed. This means that:
CASE
WHEN ts.ACCOUNTTYPE = '1' THEN ts.ACCOUNTID=SI.TENANCYID ...
END
Is fundamentally incorrect unless you work on a version of database that will allow you bool value as a value (SQL Server won't allow it for example but I think some of MySQL version used to allow it - not sure about this). You probably should write something like:
CASE
WHEN ts.ACCOUNTTYPE = '1' AND ts.ACCOUNTID=SI.TENANCYID THEN 1
WHEN ts.ACCOUNTTYPE='2' AND ts.ACCOUNTID=SI.EMPLOYEEID THEN 1
WHEN ts.ACCOUNTTYPE='3' AND ts.ACCOUNTID=SI.SUPPLIERID THEN 1
WHEN ts.ACCOUNTTYPE='4' AND ts.ACCOUNTID=SI.SALESCUSTOMERID THEN 1
ELSE 0
END = 1
Notice how the whole CASE block evaluates to 1 or 0 and then it is compared to 1. Of course instead of 4 WHEN's you could use one WHEN with combination of AND's, OR's and ( ) brackets. Of course in this particular case answer by #ppeterka 66 is correct as CASE is not suited for what you really wanted to do - I'm just trying to clarify what CASE really is.

Related

Postgres SQL state: 22P02 - invalid input syntax for integer

I'm using a sql query to export a database from my company's program.
Everything seems to be fine till I change the date on the "where" statement with a previous one.
Please find below the code:
SELECT p."Index", p."PSN" || CAST(p."PNR"as int) AS ID,
p."PSN" AS Serie, cast(p."PNR"as int) AS Numar,
pr."PINDate" AS r_gdate,
CASE WHEN pr."AsigEID"='10' THEN pr."PrimSUM" ELSE
pr."PrimSUM"*valuta1."EXCValue" END AS r_prima_lei,
CASE WHEN pr."AsigEID"='2'
THEN pr."PrimSUM"
ELSE CASE WHEN pr."AsigEID"='10' THEN pr."PrimSUM"/valuta2."EXCValue"
ELSE pr."PrimSUM"*valuta1."EXCValue"/valuta2."EXCValue"
END
END AS r_prima_eur,
CASE WHEN pr."AsigEID"='10' THEN pr."AsigSUM" ELSE
pr."AsigSUM"*valuta1."EXCValue" END as r_sa_lei,
CASE WHEN pr."AsigEID"='2'
THEN pr."AsigSUM"
ELSE CASE WHEN pr."AsigEID"='10' THEN pr."AsigSUM"/valuta2."EXCValue"
ELSE pr."AsigSUM"*valuta1."EXCValue"/valuta2."EXCValue"
END
END AS r_sa_eur,
pr."AsigStart", pr."AsigEnd", risc."Code", plink."Index"
FROM "PolsRisc" AS pr
LEFT JOIN "Pols" as p ON p."Index" = pr."PID"
LEFT JOIN "Riscs" as risc ON pr."RID" = risc."Index"
LEFT JOIN "PRLNK" plink ON plink."PTID" = p."PTID" AND plink."RID" = risc."Index"
LEFT JOIN "EXCValues" valuta1 ON valuta1."AtDate" = pr."AsigStart" AND valuta1."EID" = pr."AsigEID"
LEFT JOIN "EXCValues" valuta2 ON valuta2."AtDate" = pr."AsigStart" AND valuta2."EID"='2'
WHERE pr."PINDate" > '2020-08-01' AND pr."IsRezil" = 'false';
When I'm using '2020-08-01' the query works well. When I try to change it to a previous one eg. '2010-01-01' a get an error:
ERROR: invalid input syntax for integer: ""
SQL state: 22P02
I was looking for a solution on the previous posts but I didn't manage to solve this issue.
It looks like it is returning "" or a null value into one of the columns you are using integer logic for. The date change is just filtering out the data that would crash it.
You may need to use coalesce to reassign the nulls as 0 and then cast it back into being an int
select
cast(coalesce(table.column, 0) as int) as result
from table
I would advice to read the chapter http://www.postgresql.org/docs/current/interactive/sql-syntax-lexical.html#SQL-SYNTAX-CONSTANTS
. It's a brief and informative read.The cause for the error message is that '' is an empty string that has no representation in a numeric type like integer

Set a Variable in a case expression

I am looking to pass declared variables to build my string. I think I want to set my variable via a case expression but I have not done this before. Here is what I have done thus far.
DECLARE #stu_conv AS VARCHAR(5)
-- I think I need a select here.
set #stu_conv = CASE WHEN ITMMASTER.STU_0 ='KG' THEN'2.2'END
SELECT
YPRIMAT.YCROPYR_0
,ITMMASTER.TCLCOD_0
,SPRICLIST.DCGVAL_3
,ITMMASTER.TSICOD_2
,ITMMASTER.ACCCOD_0
,(BASPRI_0*#stu_conv) AS ImportstringAS Importstring
FROM LIVE.YPRIMAT
INNER JOIN LIVE.ITMMASTER ON YPRIMAT.ITMREF_0 = ITMMASTER.ITMREF_0
LEFT OUTER JOIN LIVE.SPRICLIST ON ITMMASTER.TCLCOD_0 = SPRICLIST.PLICRI1_0
WHERE SPRICLIST.PLICRD_0 = 'SPL000020'
I don't see the point for using a variable here, and trying to set it outside the query does not make sense, since you most likely want the value to reset for each row.
I would suggest moving the case expression into the query, as follows:
select
y.ycropyr_0,
i.tclcod_0,
s.dcgval_3,
i.tsicod_2,
i.acccod_0,
baspri_0 * case when i.stu_0 = 'KG' then 2.2 else 1 end as importstringas importstring
from live.yprimat y
inner join live.itmmaster i on y.itmref_0 = i.itmref_0
left outer join live.spriclist s on i.tclcod_0 = s.plicri1_0
where s.plicrd_0 = 'SPL000020'
I assumed that you want a value of 1 when stu_0 is not 'KG', but you can change this as needed.
Side note:
I modified your query to use table aliases. This makes the query shorter to write and somehow easier to read
you would need to prefix column baspri_0 with the table it belongs to (as your query is, it is not possible to tell)
I'm not sure why you're declaring a string and then multiplying it, but I would just inline the case (and add a default case?):
,(BASPRI_0 * CASE
WHEN ITMMASTER.STU_0 ='KG'
THEN 2.2
ELSE ???
END) AS Importstring

Issue With SQL Pivot Function

I have a SQL query where I am trying to replace null results with zero. My code is producing an error
[1]: ORA-00923: FROM keyword not found where expected
I am using an Oracle Database.
Select service_sub_type_descr,
nvl('Single-occupancy',0) as 'Single-occupancy',
nvl('Multi-occupancy',0) as 'Multi-occupancy'
From
(select s.service_sub_type_descr as service_sub_type_descr, ch.claim_id,nvl(ci.item_paid_amt,0) as item_paid_amt
from table_1 ch, table_" ci, table_3 s, table_4 ppd
where ch.claim_id = ci.claim_id and ci.service_type_id = s.service_type_id
and ci.service_sub_type_id = s.service_sub_type_id and ch.policy_no = ppd.policy_no)
Pivot (
count(distinct claim_id), sum(item_paid_amt) as paid_amount For service_sub_type_descr IN ('Single-occupancy', 'Multi-occupancy')
)
This expression:
nvl('Single-occupancy',0) as 'Single-occupancy',
is using an Oracle bespoke function to say: If the value of the string Single-occupancy' is not null then return the number 0.
That logic doesn't really make sense. The string value is never null. And, the return value is sometimes a string and sometimes a number. This should generate a type-conversion error, because the first value cannot be converted to a number.
I think you intend:
coalesce("Single-occupancy", 0) as "Single-occupancy",
The double quotes are used to quote identifiers, so this refers to the column called Single-occupancy.
All that said, fix your data model. Don't have identifiers that need to be quoted. You might not have control in the source data but you definitely have control within your query:
coalesce("Single-occupancy", 0) as Single_occupancy,
EDIT:
Just write the query using conditional aggregation and proper JOINs:
select s.service_sub_type_descr, ch.claim_id,
sum(case when service_sub_type_descr = 'Single-occupancy' then item_paid_amt else 0 end) as single_occupancy,
sum(case when service_sub_type_descr = 'Multi-occupancy' then item_paid_amt else 0 end) as multi_occupancy
from table_1 ch join
table_" ci
on ch.claim_id = ci.claim_id join
table_3 s
on ci.service_type_id = s.service_type_id join
table_4 ppd
on ch.policy_no = ppd.policy_no
group by s.service_sub_type_descr, ch.claim_id;
Much simpler in my opinion.
for column aliases, you have to use double quotes !
don't use
as 'Single-occupancy'
but :
as "Single-occupancy",

CASE WHEN SQL Syntax Error

I am attempting to us the CASE statement for the first time and I cannot understand why I am getting a syntax error on the last WHEN and ELSE. I am trying to extract a substring if a value starts with a specific set of characters. My Code is below:
SELECT
CASE
WHEN LEFT ([RCode],2) = 'BB' THEN SUBSTRING([RCode],3,LEN([RCode]))
WHEN LEFT ([RCode],4) = 'APT-' THEN SUBSTRING([RCode],5,LEN([RCode])
WHEN LEFT ([RCode],4) = 'PS-' THEN SUBSTRING([RCode],4,LEN([RCode])
ELSE [RCode]
END
FROM [Xperdyte].[dbo].[tJCLines]
Any guidance would be appreciated.
This won't (necessarily) fix your syntax problem, but I would recommend that you use like for the comparisons:
SELECT (CASE WHEN RCode LIKE 'BB%' THEN SUBSTRING([RCode], 3, LEN([RCode]))
WHEN RCode LIKE 'APT-%' THEN SUBSTRING([RCode], 5, LEN([RCode]))
WHEN RCode LIKE 'PS-%' THEN SUBSTRING([RCode], 4, LEN([RCode]))
ELSE [RCode]
END)
FROM [Xperdyte].[dbo].[tJCLines];
Then you don't have to count characters -- and the third condition will match.
Missed off two right parenthesis.
SELECT CASE WHEN LEFT([RCode],2) = 'BB'
THEN SUBSTRING([RCode],3,LEN([RCode]))
WHEN LEFT([RCode],4) = 'APT-'
THEN SUBSTRING([RCode],5,LEN([RCode]))
WHEN LEFT([RCode],4) = 'PS-'
THEN SUBSTRING([RCode],4,LEN([RCode]))
ELSE [RCode]
END
FROM [Xperdyte].[dbo].[tJCLines]

HIVE - hive subquery is not working with case when statement with IN clause

I am trying to migrate data from mysql to hive.I am not able to write a subquery case when statement with IN clause.This is my query. Can you Please help in this regard. AM i not following the proper syntax .
CREATE TABLE HIVE_TPCE_TEMP.TMP_CDMA_CD AS
SELECT A.DRI,C.BOUND_ID,A.CT_ID,A.CD_ID,A.CID,
A.TID,A.TASK_SEQ_ID,A.DIV_ID,C.BLOCK_GROUP_ID,C.ZIP_CODE,C.ROAD_CATEGORY_ID,A.RXPOWER,"${hiveconf:C_CDMA_DEVICE_ONLINE_RXPOWER_METRIC_ID}" METRIC_ID,
CASE WHEN
((A.DRI,A.DIV_ID,A.RFID) in (SELECT DRI,DIV_ID,HOME_RFID FROM HIVE_TPCE_TEMP.TMP_HOME_NETWORKS)) THEN
CASE WHEN MODE IN ('A','N') THEN "${hiveconf:HAD}" ELSE "${hiveconf:HD}" END
WHEN (COALESCE(A.RFID,0) = 0) AND ((A.DRI,A.DIV_ID,D.FR,D.SUBBAND) IN (SELECT DRI,DIV_ID,HOME_FR,
HOME_SUBBAND FROM HIVE_TPCE_TEMP.TMP_HOME_NETWORKS))
THEN CASE WHEN MODE IN ('A','N') THEN "${hiveconf:HAD}" ELSE "${hiveconf:HD}" END
ELSE CASE WHEN MODE IN ('A','N') THEN "${hiveconf:PAI}" ELSE "${hiveconf:PDI}" END END HPDA_ID
FROM HIVE_TPCE.VW_CDMA_CD A INNER JOIN HIVE_TPCE.STG_CURRENT_FILES B
ON A.DRI = B.DRI AND A.SOURCE_FILE_ID = B.SOURCE_FILE_ID
INNER JOIN
HIVE_TPCE.WRK_LOCATION C
ON A.DRI = C.DRI AND A.LOCATION_ID = C.LOCATION_ID
INNER JOIN
HIVE_TPCE.LU_RADIO D
ON A.RADIO_ID = D.RADIO_ID WHERE A.CID > 0 AND D.MODE IN ('A','N') AND A.RXPOWER IS NOT NULL AND A.CALL_RESULT_ID BETWEEN 1 AND 16;
My error signature is
FAILED: ParseException line 10:42 mismatched input ',' expecting ) near 'DRI' in expression specification
According to the Hive Language Manual: "Hive supports subqueries only in the FROM clause".
Your CASE WHEN is part of the SELECT clause, but it includes includes a SELECT subquery. Seems like that is not supported, so your syntax is not correct (in Hive).
Perhaps you could stage the data in MySQL using the query you have and then load it into Hive using a simple SELECT without CASE WHEN?
See official document.
It says
Assumptions
We plan to limit the scope with the following assumptions and limitations.
Subqueries could only be top-level expressions in SELECT. That is, subqueries in complex expressions, aggregates, UDFs, etc. will not be supported for now