Selecting column value based on another table - sql

I have two tables, one of which contains many fields including fldANA and fldPROD and another table which contains the same two fields. Not all fldANA and fldPROD fields have a matching value in table 2 however and so I don't know as if I can really join the fields? The following is what my query currently looks like but it's returning 10's or 1000's more records than it is supposed to.
SELECT Line#, CastID,
(CASE WHEN #sRst1.PROD = FN_qryIDs.fldANA AND #sRst1.PROD =
FN_qryIDs.fldPROD
THEN FN_qryIDs.fldANA ELSE #sRst1.ANA END) AS ANA,
(CASE WHEN #sRst1.PROD = FN_qryIDs.fldANA AND #sRst1.PROD =
FN_qryIDs.fldPROD
THEN FN_qryIDs.fldCONN ELSE #sRst1.CONN END) AS CONN
INTO #sRst2
FROM #sRst1
WHERE CastID <> '' AND PROD <> '' AND ANA <> ''

Ehm, not sure about the source schema but hopefully this should at least get you on the right path.
SELECT R1.[Line#], R1.CastID
,ISNULL(Q.fldANA, R1.ANA) [ANA]
,ISNULL(Q.fldCONN, R1.CONN) [Conn]
FROM #sRst1 R1
LEFT JOIN FN_qryIDs Q ON Q.fldANA = R1.PROD
AND Q.fldPROD = R1.PROD
WHERE R1.CastID <> ''
AND R1.Prod <> ''
AND R1.ANA <> ''

Related

Update Set column only if its NULL else move to next column and so on update with same data

I want to update a column when it's only NULL, else update the same data in the next column and so on.
I don't want to write 4 IF conditions, can it be possible in single CASE like below?
Below is something I am trying to achieve.
UPDATE I
SET
(CASE
WHEN I."CA_Status1" ISNULL THEN I."CA_Status1"
WHEN I."CA_Status1" IS NOTNULL THEN I."CA_Status2"
WHEN I."CA_Status2" IS NOTNULL THEN I."CA_Status3"
WHEN I."CA_Status3" IS NOTNULL THEN I."CA_Status4"
END
)
= "7".StatusCode
,I."ENC" = "7".ActionCode
FROM [dbo].[Out_P] I
INNER JOIN #TempOut_P "7"
ON I.ID = "7".Number
Since the conditions that determine whether or not a particular column is updated are related, selecting the target column could be done in a CROSS APPLY. This would simplify the resulting assignments, making them consistent and easier to read.
UPDATE I
SET
CA_Status1 = CASE WHEN S.Selector = 1 THEN "7".StatusCode ELSE I.CA_Status1 END,
CA_Status2 = CASE WHEN S.Selector = 2 THEN "7".StatusCode ELSE I.CA_Status2 END,
CA_Status3 = CASE WHEN S.Selector = 3 THEN "7".StatusCode ELSE I.CA_Status3 END,
CA_Status4 = CASE WHEN S.Selector = 4 THEN "7".StatusCode ELSE I.CA_Status4 END,
ENC = "7".ActionCode
FROM dbo.Out_P I
INNER JOIN #TempOut_P "7"
ON I.ID = "7".Number
CROSS APPLY (
SELECT Selector = CASE
WHEN I.CA_Status1 IS NULL THEN 1
WHEN I.CA_Status2 IS NULL THEN 2
WHEN I.CA_Status3 IS NULL THEN 3
WHEN I.CA_Status4 IS NULL THEN 4
END
) S

SQL Query merge

I am working on a scenario where for example I need to search customers by telephone and/or email address.
for example
if :lv_telephone <> '' then
lt_phone = select a.customer from customer_master a inner join telephone as b on a.address = b.address;
end if;
if :lv_email <> '' then
lt_email = select a.customer from customer_master a inner join email as b on a.address = b.address;
end if;
DB - HANA.
I want to create one final result merging both email and phone table only if they both have result set. Any pointers on how to do it?
You may avoid any script logic and "merge" your results in a plain SQL with conditions on variables (regardless of their source):
select a.customer
from customer_master a
left join telephone t
on a.address = t.address
and lv_telephone != ''
left join email e
on a.address = e.address
and lv_email != ''
where 1 = 1
/*Applies only when lv_telephone is not ''*/
and map(lv_telephone, '', '', t.address) is not null
/*Applies only when lv_email is not ''*/
and map(lv_email, '', '', e.address) is not null
This may also be adapted if you need to filter by passed values: compare with variable value instead of null. If variables come from SQLScript code, this can be embedded into SQLScript code. If they come from outside (e.g. some external language communicating with your DB), you may use bind variables and plain SQL withour additional script wrapper.
Below is example with standard SAP tables:
create procedure test_sp ( in iv_tel nvarchar(10), in iv_email nvarchar(10))
as
begin
select b.*
from sapdbh.t006 as b
left join sapdbh.t006a as t
on b.msehi = t.msehi
and t.spras = 'R'
and :iv_tel != ''
left join sapdbh.t006t as e
on b.dimid = e.dimid
and e.spras = 'R'
and :iv_email != ''
where 1 = 1
and case
when :iv_tel != ''
then t.msehi
else ''
end is not null
and case
when :iv_email != ''
then e.dimid
else ''
end is not null
;
end;
And execution plans below (I didn't use mandt in join so you may observe results are multiplied when join is introduced):
With call test_sp('', ''); one table accessed.
With call test_sp('X', ''); two tables accessed.
With call test_sp('X', 'X'); three tables accessed.

Summing using a case expression

I am looking to roll up my numbers.
SELECT
SORDERQ.SOHNUM_0,
YQTYORD_0,
ORDINVNOT_0
FROM LIVE.SORDER
LEFT JOIN LIVE. SORDERQ ON SORDER.SOHNUM_0 = SORDERQ.SOHNUM_0
WHERE SORDER.SOHNUM_0 = 'SC111-162420_19'
AND ZBPSELECTION_0 <> ''
AND YCROPYR_0 = '2019'
AND SORDER.SALFCY_0 = '111'
I want to return 1 record per SOHNUM_0,the sum of YQTYORD_0 by SOHNUM_0 and ORDINVNOT_0.
I want to return 1 record per SOHNUM_0,the sum of YQTYORD_0 by SOHNUM_0 and ORDINVNOT_0.
Are you just looking for simple aggregation?
SELECT
q.SOHNUM_0,
SUM(YQTYORD_0) SUM_YQTYORD_0,
ORDINVNOT_0
FROM LIVE.SORDER o
LEFT JOIN LIVE.SORDERQ q ON o.SOHNUM_0 = q.SOHNUM_0
WHERE
o.SOHNUM_0 = 'SC111-162420_19'
AND o.SALFCY_0 = '111'
AND ZBPSELECTION_0 <> ''
AND YCROPYR_0 = '2019'
GROUP BY
q.SOHNUM_0,
ORDINVNOT_0
Note:
I modified your query so it uses table aliases - this makes it shorter
you should prefix all columns in the query with the table they belong to, to make your query unmabiguous and easier to understand

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).

Matching criteria for the below scenario

Refer to above image. I had tables Diagnoses,Services and PreventativeServices in which i have a common field named DxCode in diagnosis and PreventativeServices. DxCode in PreventativeServices table is an optional field as it acts as a configuration table for us. Suppose DxCode = DiagnosisCode, I have following scenarios, based on image:
If we have DxCode in both services and diagnosis table then compare it on DxCode and resultant row should be output of the comparison. If found output will be 10060 else no row.
If we have DxCode = null or blank in PreventativeServices then again output will be 10060.
If we dont have rows in our Diagnosis table against RegistrationId = 247237 but we have a row in PreventativeServices with along with diagnosis code then again resultant will be no row, else
out put will be 10060
I had following query for the same:
SELECT [ServiceID] AS PreventativeServiceId,
[CPTCode]
FROM PreventativeService ps
INNER JOIN [Services] s(NOLOCK)
ON ps.CPTCode = s.ServiceCode
LEFT JOIN Diagnoses dx(NOLOCK)
ON dx.RegistrationID = s.RegistrationID
WHERE s.RegistrationId = #RegistrationId
AND ps.IsActive = 1
AND #AdmitDate BETWEEN ps.StartDate AND Isnull(PS.EndDate, #AdmitDate)
AND #Gender = Isnull(ps.Gender, #Gender)
AND #Age BETWEEN Isnull(ps.AgeFrom, #Age) AND Isnull(ps.AgeTo, #Age)
AND dx.DiagnosisCode = ( CASE
WHEN Rtrim(Ltrim(ps.DiagnosisCode)) = '' THEN dx.DiagnosisCode
ELSE ps.DiagnosisCode
END )
NOTE
DiagnosisCode in PreventativeServices will contain null and blank as well.
Requirement
dx.DiagnosisCode = ( CASE
WHEN Rtrim(Ltrim(ps.DiagnosisCode)) = '' THEN dx.DiagnosisCode
ELSE ps.DiagnosisCode
END )
is failing for scenario , when I have blank('') diagnosis in PreventativeServices and no row in Diagnosis table
ok, This is because null=null always returns false. You can try using isnull function.
isnull(dx.DiagnosisCode,' ') = (
CASE
WHEN rtrim(ltrim(ps.DiagnosisCode)) = ''
THEN isnull(dx.DiagnosisCode,' ')
ELSE ps.DiagnosisCode
END
)