Case statement on a join in where clause - sql

I am trying to use a CASE statement inside a WHERE clause for joining 2 tables. I want to evaluate POSITION_NBR2, if it is blank (null) then I want to join A.POSITION_NBR2 = B.POSITION_NBR Else I want to join A.POSITION_NBR = B.POSITION_NBR , however I am getting syntax errors while trying to run the following:
UPDATE #WORKTABLE
SET SLT_MEMBER = B.NAME
FROM PS_GHS_FTE_SLT A,
PS_EMPLOYEES B,
#WORKTABLE C
WHERE
CASE WHEN A.POSITION_NBR2 <> '' THEN A.POSITION_NBR2 = B.POSITION_NBR
ELSE A.POSITION_NBR = B.POSITION_NBR
END
AND A.DEPTID COLLATE Latin1_General_BIN = C.DEPTID COLLATE Latin1_General_BIN
AND B.EMPL_STATUS = 'A'

Use proper JOIN syntax and reasonable table aliases:
UPDATE WT
SET SLT_MEMBER = E.NAME
FROM PS_GHS_FTE_SLT GFS JOIN
PS_EMPLOYEES E
ON E.POSITION_NBR = (CASE WHEN GFS.POSITION_NBR2 <> '' THEN GFS.POSITION_NBR2 ELSE GFS.POSITION_NBR
END) JOIN
#WORKTABLE WT
ON GFS.DEPTID COLLATE Latin1_General_BIN = WT.DEPTID COLLATE Latin1_General_BIN
WHERE E.EMPL_STATUS = 'A';
I'm generally not a fan of using CASE for ON and WHERE clauses. In this case, though, it is only selectively choosing one column, so it doesn't bother me so much.

Related

Oracle SQL - Case statement with iteration

The ASCII table values should be compared to the s.manure_type. For each record in the following table below the QuantityText case statement should do a comparison. The value it needs to select is e.g. oats,velvet beans, other none.
select
c.id customer_num,
c.type type,
s.id_text sample_num,
c.sasa_grower_code s_grower,
c.address s_address1,
c.postalcode s_post_code,
c.email q1_email,
nvl(c.client_name, c.farm_name )s_company,
c.farm_name s_estate,
c.contact_name s_contact,
s.id_numeric id_numeric,
s.id_text fas_lab_id,
s.date_received received_date,
s.date_printed printed_date,
s.sampled_date sampled_date,
e.name S_AREA_DESCRIP,
a.name s_advisor_name,
a.email s_advisor_email,
s.order_no s_order_num,
s.field_name s_field,
p.phrase_text || ' cm' sample_depth,
cr.crop_name s_crop,
s.attyield s_yield,
s.variety s_varty,
case when s.flg_trashed is null then
'None'
else (case when s.flg_trashed = constant_pkg.get_true then
'Yes'
else (case when s.flg_trashed = constant_pkg.get_false then
'No'
else ' '
end)
end) end trashed,
case when s.flg_irrigated is null then
'None'
else (case when s.flg_irrigated = constant_pkg.get_true then
'Yes'
else (case when s.flg_irrigated = constant_pkg.get_false then
'No'
else ' '
end)
end) end s_irrig,
CASE
WHEN trim(s.manure_type) in (select p.phrase_id from phrase p where p.phrase_type = 'AL_G_MANUR') then (select p.phrase_text from phrase p)
END AS QuantityText,
'' S_GM_YIELD,
s.project_code project_code,
s.trial_ref trial_ref,
s.cost_centre cost_centre
from client c
left outer join sample s on (s.client_id = c.id)
left outer join extension e on (e.id = c.extension_id)
left outer join advisor a on (a.id = c.advisor_id)
left outer join phrase p on (p.phrase_id = s.depth)
left outer join crop cr on (cr.id = s.crop_id)
where p.phrase_type = phrase_pkg.get_soil_depth
and c.id = '211493A'
and s.fas_sample_type = sample_pkg.get_soil_sample
and s.flg_recommendation = sample_pkg.get_flg_recommendation
and s.id_numeric between 14932 and 14933
+----------------------------+
| Phrase |
+----------------------------+
|AL_G_MANUR OA Oats |
|AL_G_MANUR V Velvet Beans
|AL_G_MANUR O Other
|AL_G_MANUR N None |
+----------------------------+
But I get the error ORA-00900: Single row query returns more than one row
Missing where clause in one of the case statements is most likely the cause.
CASE
WHEN trim(s.manure_type) in
(select p.phrase_id from phrase p where p.phrase_type = 'AL_G_MANUR')
then (select p.phrase_text from phrase p) <<< NO WHERE CLAUSE ?
END AS QuantityText,
This is relatively easy to debug yourself.
Remove a single selected column
Check if error still occurs
If it does, go back to 1.
If it does not then verify why last added column errors
Problem is in the following statement
then (select p.phrase_text from phrase p)
I guess, It should be replaced with this
(select p.phrase_text from phrase p where p.phrase_type = 'AL_G_MANUR')

Convert value ' ' to null in SQL or BigQuery

I have the following extraction query
select A.documentid.Docid, A.documentId.Appid, A.timestamp, A.EventStatus, D.Sequence, D.EventAppName, E.Value as Federation
from `dbo.events` A left join `dam.eventsroot` B on A.documentid.docid = B.docid left join `dbo.documentroot` C on B.rootdocid=C.rootdocid
inner join `dbo.reference_status` D
on A.DocumentID.AppID=D.EventAppID and A.EventStatus = D.EventStatus left join unnest(C.metadata) E on E.Key='Federation'
where A.timestamp > TIMESTAMP_TRUNC(CURRENT_TIMESTAMP(),DAY)
The result is that in column FEDERATION i get different values and values of '' (nothing) and i want to change them to Null.
How can i do this?
Thank you very much
I could use this in simple way like
select A.documentid.Docid, A.documentId.Appid, A.timestamp, A.EventStatus,
D.Sequence, D.EventAppName,
Case
When LTrim(RTrim(E.Value)) = '' Then Null
Else E.Value
End AS Federation
from dbo.events A
left join dam.eventsroot B on A.documentid.docid = B.docid
left join dbo.documentroot C on B.rootdocid=C.rootdocid
inner join dbo.reference_status D on A.DocumentID.AppID=D.EventAppID and
A.EventStatus = D.EventStatus
left join unnest(C.metadata) E on E.Key='Federation'
where A.timestamp > TIMESTAMP_TRUNC(CURRENT_TIMESTAMP(),DAY)
there are functions like NULLIF(column , '') and REPLACE(column,'',NULL) which you can them in such this cases. u can use LTRIM(RTRIM(column)) so any extra spaces will be removed.
so like:
NULLIF(LTRIM(RTRIM(federation)), '')
REPLACE(LTRIM(RTRIM(federation)),'',NULL)
and so many other ways...
You can use nullif() in any database:
select nullif(federation, '')
You might want to remove white space in general, and do:
select nullif(trim(federation), '')
Or, perhaps:
select (case when trim(federation) <> '' then federation end)

How to use a non-existing column in sql query

I am working in SQL server 2012. I have to write a sql statement where I first assign a value to [Pay_Type], which is a non-existing column (not sure whether it can be called as variable or not) and based upon its value I want to use it in another case statement as shown below
SELECT sp.First_Name, [Pay_Type] = CASE WHEN NOT EXISTS(SELECT '1' FROM
PERSON_SALARY ps WHERE ps.PARTY_ID = sp.PARTY_ID and ps.END_DATE IS NULL)
THEN 'Hourly' ELSE 'Salary' END,
HOURLY_RATE = CASE WHEN [Pay_Type] = 'Hourly' THEN pj.HOURLY_RATE ELSE
'0.00' END
FROM SEC_PERSON sp
LEFT OUTER JOIN PERSON_JOB pj ON sp.PERSON_ID = pj.PERSON_ID
WHERE sp.END_DATE IS NOT NULL
But I am getting "Invalid column name 'Pay_Type' " error.
Column aliases cannot be re-used in the same SELECT where they are define. The typical answer is to use a subquery or CTE. I also like using a lateral join:
SELECT sp.First_Name, s.Pay_Type,
HOURLY_RATE = (CASE WHEN s.Pay_Type = 'Hourly' THEN pj.HOURLY_RATE ELSE
'0.00' END)
FROM SEC_PERSON sp LEFT OUTER JOIN
PERSON_JOB pj
ON sp.PERSON_ID = pj.PERSON_ID OUTER APPLY
(SELECT (CASE WHEN NOT EXISTS (SELECT 1
FROM PERSON_SALARY ps
WHERE ps.PARTY_ID = sp.PARTY_ID and ps.END_DATE IS NULL
)
THEN 'Hourly' ELSE 'Salary'
END) as PayType
) s
WHERE sp.END_DATE IS NOT NULL

Condition if sql

I have this query
SELECT
SI_Num_Inventario = COALESCE (t.SI_Num_Inventario, c.SI_Num_Inventario),
SI_Ubicacion = COALESCE(t.SI_Ubicacion, c.SI_Ubicacion),
SI_Ubicacion_Fisica = COALESCE(t.SI_Ubicacion_Fisica, c.SI_Ubicacion_Fisica),
SI_Num_Articulo = COALESCE(t.SI_Articulo, c.SI_Num_Articulo),
NULL,
SI_Num_Conteo = COALESCE(cs.SI_Num_Conteo,2),
GETDATE(),
'Admin',
c.SI_OV
FROM
SI_Inventario_Teorico_QAD t
FULL JOIN
SI_Conteo c ON t.SI_Articulo = c.SI_Num_Articulo
AND t.SI_Ubicacion = c.SI_Ubicacion
INNER JOIN
SI_Maestro_Ref_QAD m ON t.SI_Articulo = m.SI_Num_Articulo
OR c.SI_Num_Articulo = m.SI_Num_Articulo
FULL JOIN
SI_Consecutivo cs ON c.SI_Num_Inventario = cs.SI_Num_Inventario
AND cs.SI_Estado = 0
WHERE
c.SI_Num_Articulo = 201423 OR t.SI_Articulo = 201423
And I'm trying to tell you that if c.SI_OV IS NULL INSERT THIS `INSERT INTO``
IF c.SI_OV IS NULL
INSERT INTO SI_Conteo(SI_Num_Inventario, SI_Ubicacion,SI_Num_Articulo, SI_Cantidad,SI_Num_Conteo,SI_Fecha_Conteo, SI_Usuario,SI_OV)
And if it is not NULL insert me this other
ELSE
INSERT INTO SI_Conteo(SI_Num_Inventario, SI_Ubicacion_Fisica, SI_Num_Articulo, SI_Cantidad,SI_Num_Conteo,SI_Fecha_Conteo, SI_Usuario,SI_OV)
END IF;
In short: the CASE construct needs to "live" in your SELECT clause of you SQL statement. The receiving INSERT clause should always mention both column names like this
INSERT INTO SI_CONTEO (SI_Num_Inventario,
SI_Ubicacion, SI_Ubicacion_fisico,
SI_Num_Articulo, SI_Cantidad,SI_Num_Conteo,
SI_Fecha_Conteo, SI_Usuario,SI_OV)
SELECT SI_Num_Inventario = COALESCE (t.SI_Num_Inventario,c.SI_Num_Inventario),
SI_Ubicacion = CASE WHEN SI_OV IS NULL THEN COALESCE(t.SI_Ubicacion, c.SI_Ubicacion) END,
SI_Ubicacion_Fisica = CASE WHEN NOT SU_OV IS NULL THEN COALESCE(t.SI_Ubicacion_Fisica, c.SI_Ubicacion_Fisica) END,
SI_Num_Articulo = COALESCE(t.SI_Articulo, c.SI_Num_Articulo),
NULL, ...
if else in non query language ~= CASE WHEN cond1 ELSE cond2 END in SQL
Use the below query:
INSERT INTO SI_Conteo(SI_Num_Inventario,SI_Ubicacion,SI_Ubicacion_Fisica,SI_Num_Articulo, SI_Cantidad,SI_Num_Conteo,SI_Fecha_Conteo,
SI_Usuario,SI_OV)
SELECT
SI_Num_Inventario = COALESCE (t.SI_Num_Inventario,c.SI_Num_Inventario),
(CASE WHEN c.SI_OV IS NULL THEN COALESCE(t.SI_Ubicacion, c.SI_Ubicacion) ELSE NULL END)AS SI_Ubicacion,
(CASE WHEN c.SI_OV IS NOT NULL THEN COALESCE(t.SI_Ubicacion_Fisica, c.SI_Ubicacion_Fisica) ELSE NULL END)AS SI_Ubicacion_Fisica,
SI_Num_Articulo = COALESCE(t.SI_Articulo, c.SI_Num_Articulo),
NULL,
SI_Num_Conteo = COALESCE(cs.SI_Num_Conteo,2),
GETDATE(),
'Admin',
c.SI_OV
FROM SI_Inventario_Teorico_QAD t
full JOIN SI_Conteo c
ON t.SI_Articulo = c.SI_Num_Articulo
AND t.SI_Ubicacion = c.SI_Ubicacion
INNER JOIN SI_Maestro_Ref_QAD m
ON t.SI_Articulo = m.SI_Num_Articulo
OR c.SI_Num_Articulo = m.SI_Num_Articulo
FULL JOIN SI_Consecutivo cs
ON c.SI_Num_Inventario = cs.SI_Num_Inventario
AND cs.SI_Estado = 0
WHERE c.SI_Num_Articulo = 201423 OR t.SI_Articulo = 201423
Basicallly I have combined both inserts into one Insert, which includes both of the columns , where you want a switch based on Case. Only one column out of SI_Ubicacion and SI_Ubicacion_Fisica will be set based on s.SI_OV value. Hope you got what I am saying,.
Note: I Could not execute this as I don't have any table structure/data with me. I have modified your query manually and posted it here.
Clarify your question. You have a select statement that returns a resultset of some number of rows. You propose to insert them into a table. You claim to need to use if/else (or similar) but it is not clear why. Your proposed insert statements differ by a single column - is that correct? If so, then you probably need to use 2 different insert statements - one to handle the non-null situation and one to handle the null situation. You cannot dynamically change the column list of the inserted table.
OTOH, perhaps you just want to swap the value inserted into the SI_Ubicacion column of the SI_Conteo table? If so, you can probably use isnull or coalesce in the select statement (much like you do now - just differently).

Join tables and groupby results based on user defined parameters in sql server 2008

I want to join two tables and group by the result based on a user defined parameter in Sql Server 2008. I tried the query below but it is not working. I appreciate if someone helps me to see my mistake and correct it for me. Regards.
Select TotalVolume= SUM(volume),
PrimGroup = r.PrimaryGroup, SnGroup = r.SecondaryGroup
from Requests r
inner join #Calculations c on
case #PrimaryId is not null then c.PrimaryGroup = r.PrimaryGroup end
and case #SecondaryId is not null then c.SecondaryGroup = r.SecondaryGroup end
and c.SrgId = r.SrgId
group by
case #PrimaryId is not null then r.PrimaryGroup end,
case #SecondaryId is not null then r.SecondaryGroup end
Try this:
Select TotalVolume= SUM(volume),
PrimGroup = r.PrimaryGroup, SnGroup = r.SecondaryGroup
from Requests r
inner join #Calculations c on
((#PrimaryId is null) or
(#PrimaryId is not null) and c.PrimaryGroup = r.PrimaryGroup)
and ((#SecondaryId is null) or
(#SecondaryId is not null) and c.SecondaryGroup = r.SecondaryGroup)
and c.SrgId = r.SrgId
group by
case when #PrimaryId is not null then r.PrimaryGroup end,
case when #SecondaryId is not null then r.SecondaryGroup end