Using CASE in WHERE clause in Oracle 12c - oracle

I have a select statement like below :
SELECT * FROM
(SELECT d.value, d.line, d.language, l.pos_id, l.vehicle_id,l.vehicle_given
FROM Vehicle_value d,
vehicle_document l
WHERE d.gen_id = l.gen_id
AND d.pos_id = l.pos_id
AND d.gen_id = 1255) d1
LEFT OUTER JOIN
(SELECT d.value, d.line, d.language, l.pos_id, l.vehicle_id,l.vehicle_given
FROM TBB_GEN_Daten d,
TBB_GEN_Lesehilfe l
FROM Vehicle_value d,
vehicle_document l,
WHERE d.gen_id = l.gen_id
AND d.pos_id = l.pos_id
AND d.gen_id = 1254) d2
ON d1.value = d2.value
AND d1.pos_id = d2.pos_id
AND case when d1.vehicle_given = 'YES' then (d1.vehicle_id = d2.vehicle_id)
else end
AND d1.value is not null;
So I wanted to compare the d1.vehicle_id to d2.vehicle_id only when the d1.vehicle_given value is 'YES'. But the case statement i have used here is wrong and hence it doesnt work. is there any other to do this comparision ?

Bunch of typos in your code, but - when fixed, and with CASE being rewritten - query looks like this:
SELECT *
FROM (SELECT d.VALUE,
d.line,
d.language,
l.pos_id,
l.vehicle_id,
l.vehicle_given
FROM Vehicle_value d, vehicle_document l
WHERE d.gen_id = l.gen_id
AND d.pos_id = l.pos_id
AND d.gen_id = 1255) d1
LEFT OUTER JOIN (SELECT d.VALUE,
d.line,
d.language,
l.pos_id,
l.vehicle_id,
l.vehicle_given
FROM TBB_GEN_Daten d,
TBB_GEN_Lesehilfe l,
Vehicle_value d,
vehicle_document l
WHERE d.gen_id = l.gen_id
AND d.pos_id = l.pos_id
AND d.gen_id = 1254) d2
ON d1.VALUE = d2.VALUE
AND d1.pos_id = d2.pos_id
AND d1.vehicle_id =
CASE
WHEN d1.vehicle_given = 'YES' THEN d2.vehicle_id
ELSE d1.vehicle_id
END
AND d1.VALUE IS NOT NULL;

Use brackets and an OR condition for either the matching condition or when it is not YES:
AND ( d1.vehicle_given <> 'YES'
OR d1.vehicle_given IS NULL
OR d1.vehicle_id = d2.vehicle_id )
If you use a CASE expression such as:
AND d1.vehicle_id = CASE
WHEN d1.vehicle_given = 'YES'
THEN d2.vehicle_id
ELSE d1.vehicle_id
END
Then when the ELSE condition is matched you will effectively end up with AND d1.vehicle_id = d1.vehicle_id. This, naively, looks like it should be fine but if d1.vehicle_id is NULL then you will end up comparing NULL = NULL and the result is not truthy and the row will be excluded and that is not what you want.

Related

Oracle Query not giving result though outer join is present

In the below query when i comment one line AND EVT.EVT_EVNT_ID(+) = DPT.DPT_EVNT_ID or add outer join (+) in one line AND EVT.EVT_ENTITY_ID ='G' the query will fetch results, else it will not give any results.
`
select * from
(select B11.ext_db_id,B11.FRST_LINE_OF_PRFRD_NAME, E11.*, D1.D1_evnt_id,
(SELECT E1.E1_DT
FROM S1core.E1_EVNT_DT_DTLS E1
WHERE E1.E1_ENTITY_ID = D1.D1_ENTITY_ID
AND E1.E1_EVNT_ID = D1.D1_EVNT_ID
AND E1.E1_D1_ID = D1.D1_D1_ID
AND E1.E1_DT_TYP = 'MEET'
AND E1.E1_OPTN_SEQ_N = '999'
AND E1.STATUS = 'AUTHD' ) "MEET_DATE"
FROM S1core.E1_EVNT_DT_DTLS E11, S1core.SECURITY_ACCOUNT SFA,
S1core.EXTRNL_SYS_DETAILS EXT,
S1core.D1_DPOT_EVNT_DTLS D1, S1core.IP_ACNT_RELATION i1,
S1core.ELG_ELGBLTY E1,S1core.P1_D1_PRXY_DTLS P1, S1core.EVT_DTLS EVT,
S1core.BUSINESS_PARTNER B1, S1core.BUSINESS_PARTNER B11
WHERE
P1.P1_EVNT_ID(+) = D1.D1_EVNT_ID
AND B1.BP_ID = i1.IP_ID
AND SFA.BP_ID = B11.BP_ID
AND B11.OWNER_ENTITY = SFA.OWNER_ENTITY
AND P1.P1_D1_ID(+) = D1.D1_D1_ID
AND P1.P1_ENTITY_ID(+) = D1.D1_ENTITY_ID
AND P1.STATUS(+) = 'AUTHD'
AND EXT.LVL_REF = SFA.SCA_REF
AND EXT.OWNER_ENTITY = SFA.owner_entity
AND EXT.EXTRNL_SYS_ID = '39'
AND EXT.BP_ID = SFA.BP_ID
AND EXT.LVL = 5
AND E1.ELG_SEC_ID = D1.D1_SEC_ID
AND D1.D1_ENTITY_ID = E1.ELG_ENTITY_ID
AND D1.D1_EVNT_ID = E1.ELG_EVNT_ID
AND D1.D1_D1_ID = E1.ELG_D1_ID
AND E1.ELG_ENTITY_ID = SFA.OWNER_ENTITY
AND E1.ELG_ACNT_ID = SFA.SCA_REF
AND i1.owner_entity = SFA.OWNER_ENTITY
AND i1.owner_entity = B1.OWNER_ENTITY
AND i1.SCA_REF = SFA.SCA_REF
AND i1.stat <> 2
AND EVT.EVT_ENTITY_ID ='G'
AND EVT.EVT_EVNT_ID(+) = D1.D1_EVNT_ID
AND EVT.STATUS(+) = 'AUTHD'
AND E11.E1_ENTITY_ID = D1.D1_ENTITY_ID
AND E11.E1_EVNT_ID = D1.D1_EVNT_ID
AND E11.E1_D1_ID = D1.D1_D1_ID
AND D1.D1_EVNT_GRP = 'MEETING'
AND E1.ELG_FNL_ELGBL_QNTTY > 0
AND D1.D1_ENTITY_ID = 'GSSIN' -- P_D1_ENTITY_ID
AND B11.ext_db_id LIKE 'LICMF' -- P_GLOBAL_CUSTODIAN
AND B1.ext_db_id LIKE '%' -- P_FUND_MANAGER
AND SUBSTR(EXT.LEVEL_EXTNL_SYS,1,5) LIKE '%' -- P_SUB_ACCOUNT_ID
AND SUBSTR(EXT.LEVEL_EXTNL_SYS,6,9) LIKE '%' -- P_SCHEMA_ID
AND SUBSTR( D1.D1_EVNT_TYP, 1, 4 ) LIKE '%' -- P_EVENT_TYPE
AND E11.E1_DT_TYP = 'MEET'
and D1.D1_evnt_id='12457886544'
AND D1.OU_ID IN('17','80') -- ('S1 INDIA PC')
) ;
Am I missing any outer join or the query is having any other issue as i can see that dpt_evnt_id='12457886544'is available in all tables.
`
I tried to run this query by commenting AND EVT.EVT_EVNT_ID(+) = DPT.DPT_EVNT_ID
and by adding outer join in EVT.EVT_ENTITY_ID (+) ='G'
You have:
AND EVT.EVT_ENTITY_ID ='G'
AND EVT.EVT_EVNT_ID(+) = D1.D1_EVNT_ID
AND EVT.STATUS(+) = 'AUTHD'
Even though the second two have (+) the first one does not so the join to EVT will be treated as an INNER JOIN and not an OUTER JOIN.
You should convert your code to use ANSI joins as it will be much easier to spot issues like this.
Note: There may be more issues like this. However, your code has so many joins, the syntax is archaic, and we have no way of validating the correctness that I stopped looking after finding the first issue. You are going to need to debug it all to check for any other issues.

ORA-00904: "S"."AIR_TIME": invalid identifier

Why does this code show invalid identifier when sum is used in distance and air_time column?
When sum is not used this statement process successfully but using sum I get error? I need to use sum for this statement.
MERGE INTO FACT_COMPANY_GROWTH F
USING (SELECT DISTINCT TIME_ID, FLIGHT_KEY, AEROPLANE_KEY, SUM(DISTANCE) AS TOTAL_DISTANCE, SUM(AIR_TIME) AS TOTAL_AIRTIME
FROM TRANSFORM_FLIGHT T
INNER JOIN TRANSFORM_AEROPLANE A
ON T.FK_AEROPLANE_KEY = A.AEROPLANE_KEY
INNER JOIN DIM_TIME D
ON D.YEAR = T.YEAR
AND D.MONTH = T.MONTH
GROUP BY TIME_ID, FLIGHT_KEY, AEROPLANE_KEY) S
ON (F.FK1_TIME_ID = S.TIME_ID
AND F.FK2_FLIGHT_KEY = S.FLIGHT_KEY
AND F.FK3_AEROPLANE_KEY = S.AEROPLANE_KEY
)
WHEN MATCHED THEN
UPDATE SET
F.TOTAL_AIRTIME = S.AIR_TIME,
F.TOTAL_DISTANCE = S.DISTANCE,
F.TOTAL_NO_OF_FLIGHTS = S.FLIGHT_KEY,
F.TOTAL_NO_OF_AEROPLANE = S.AEROPLANE_KEY
WHEN NOT MATCHED THEN
INSERT(FACT_ID, FK1_TIME_ID, FK2_FLIGHT_KEY, FK3_AEROPLANE_KEY, TOTAL_DISTANCE, TOTAL_AIRTIME, TOTAL_NO_OF_FLIGHTS, TOTAL_NO_OF_AEROPLANE)
VALUES
(NULL, S.TIME_ID, S.FLIGHT_KEY, S.AEROPLANE_KEY, S.DISTANCE, S.AIR_TIME, S.FLIGHT_KEY, S.AEROPLANE_KEY);
USING(
SELECT DISTINCT
TIME_ID,
FLIGHT_KEY,
AEROPLANE_KEY,
SUM(DISTANCE) AS TOTAL_DISTANCE,
SUM(AIR_TIME) AS TOTAL_AIRTIME
...) S
The problem is at UPDATE SET F.TOTAL_AIRTIME = S.AIR_TIME. There are 5 fields defined in S and none is named AIR_TIME.
UPDATE SET
F.TOTAL_AIRTIME = S.TOTAL_AIRTIME,
F.TOTAL_DISTANCE = S.TOTAL_DISTANCE,

C#: LINQ not returning the same result as SQL

I'm trying to convert the following SQL query to LINQ, but getting different result count with both,
SQL Query:
SELECT T5.CNTR, T5.BenefitCode,T5.ApprovedFlag,
T5.PaymentFrequencyCode, T5.InstalmentAmt, T5.TotalAmt,
T5.CarRego
FROM
dbo.EmployeeBenefit As T5
LEFT JOIN dbo.Payee ON T5.PayeeCntr = dbo.Payee.CNTR
LEFT JOIN dbo.BankDetails ON dbo.Payee.BankCntr = dbo.BankDetails.BankCntr
Left Join dbo.EmployeeCar As T4 on T5.EmployeeCarCntr=T4.Cntr
Inner Join dbo.EmployeeEntity As T1 On T5.EmployeeEntityCntr=T1.EmployeeEntityCntr
Inner Join dbo.EmployerEntity As T2 On T1.EmployerEntityCntr=T2.EmployerEntityCntr
where T5.EmployeeCntr = 117165
AND ((T5.EndDate is Null) OR (T5.EndDate >= GETDATE()))
LINQ:
var result = (from employeeBenefit in context.EmployeeBenefit
from payee in context.Payee.Where(x => x.Cntr == employeeBenefit.PayeeCntr).DefaultIfEmpty()
from bankDetails in context.BankDetails.Where(x => x.BankCntr == employeeBenefit.PayeeCntr).DefaultIfEmpty()
from employeeCar in context.EmployeeCar.Where(x => x.Cntr == payee.BankCntr).DefaultIfEmpty()
from employeeEntity in context.EmployeeEntity
where employeeEntity.EmployeeEntityCntr == employeeBenefit.EmployeeEntityCntr
from employeeEntity1 in context.EmployeeEntity
where employeeEntity.EmployerEntityCntr == employeeEntity1.EmployerEntityCntr
&& employeeBenefit.EmployeeCntr == iEmployeeID
&& (!employeeBenefit.EndDate.HasValue || employeeBenefit.EndDate >= DateTime.Now)
&& employeeBenefit.EmployeeCntr == 117165
&& employeeBenefit.CarRego == registration
select new
{
CNTR = employeeBenefit.Cntr,
BenefitCode = employeeBenefit.BenefitCode,
PaymentFrequencyCode = employeeBenefit.PaymentFrequencyCode,
InstalmentAmount = employeeBenefit.InstalmentAmt,
TotalAmount = employeeBenefit.TotalAmt,
CarRego = employeeBenefit.CarRego,
ApprovedFlag = employeeBenefit.ApprovedFlag
}).ToList();
Please let me know what i'm missing.
For the data in my database the SQL query is returning 10 records. But, the LINQ is returning 2700 records.
Not a full answer (I'm late for work) but:
var result = (from T5 in context.EmployeeBenefit
join PY in dbo.Payee on T5.PayeeCntr equals PY.CNTR into PY1
where T5.EmployeeCntr = 117165
select new {
CNTR = T5.Cntr,
...
}
).ToList();
It was the issue with the condition mismatch that i had done in the LINQ. The below query just worked fine. Thank you for helping me with the issue.
var result = (from employeeBenefit in context.EmployeeBenefit
from payee in context.Payee.Where(x => x.Cntr == employeeBenefit.PayeeCntr).DefaultIfEmpty()
from bankDetails in context.BankDetails.Where(x => x.BankCntr == payee.BankCntr).DefaultIfEmpty()
from employeeCar in context.EmployeeCar.Where(x => x.Cntr == employeeBenefit.EmployeeCarCntr).DefaultIfEmpty()
join employeeEntity in context.EmployeeEntity
on employeeBenefit.EmployeeEntityCntr equals employeeEntity.EmployeeEntityCntr
join employerEntity in context.EmployerEntity
on employeeEntity.EmployerEntityCntr equals employerEntity.EmployerEntityCntr
where employeeBenefit.EmployeeCntr == 117165 && (!employeeBenefit.EndDate.HasValue || employeeBenefit.EndDate >= DateTime.Now)
select new
{
CNTR = employeeBenefit.Cntr,
BenefitCode = employeeBenefit.BenefitCode,
PaymentFrequencyCode = employeeBenefit.PaymentFrequencyCode,
InstalmentAmount = employeeBenefit.InstalmentAmt,
TotalAmount = employeeBenefit.TotalAmt,
CarRego = employeeBenefit.CarRego,
ApprovedFlag = employeeBenefit.ApprovedFlag
}).ToList();

Update/Merge multiple rows with select statement data

Im trying to update a single table with output of a select statement which returns two values. One is the accountid that I need to update in the table, and the other is the information I need to update.
Here is my select statement
select CTP.CARETEAMPATIENTID, O.ORGANIZATIONID
from acts.careteampatient ctp,
ods.member m,
ods.supplierorganization so,
ods.MASTERSUPPLIERSUPPLIERRELATION mssr,
ods.INSURANCEORGSUPPLIERRELATION IOSR,
ods.INSURANCEORGANIZATION IO,
acts.organization o
where ctp.accountorgid is null
and m.primarymemberplanid = ctp.primarymemberplanid
and SO.AHMSUPPLIERID = M.AHMSUPPLIERID
and mssr.SUPPLIERID = so.SUPPLIERORGID
AND iosr.SUPPLIERID = so.SUPPLIERORGID
AND io.INSURANCEORGID = iosr.INSURANCEORGID
and io.processingmodecd = 'P'
and so.usagemnemonic = 'P'
and O.ODSACCOUNTID = IO.INSURANCEORGID
and O.ACCOUNTFLG = 'Y'
I want to do something along the lines of
update careteampatient
from (select CTP.CARETEAMPATIENTID patientid, O.ORGANIZATIONID orgid
from acts.careteampatient ctp,
ods.member m,
ods.supplierorganization so,
ods.MASTERSUPPLIERSUPPLIERRELATION mssr,
ods.INSURANCEORGSUPPLIERRELATION IOSR,
ods.INSURANCEORGANIZATION IO,
acts.organization o
where ctp.accountorgid is null
and m.primarymemberplanid = ctp.primarymemberplanid
and SO.AHMSUPPLIERID = M.AHMSUPPLIERID
and mssr.SUPPLIERID = so.SUPPLIERORGID
AND iosr.SUPPLIERID = so.SUPPLIERORGID
AND io.INSURANCEORGID = iosr.INSURANCEORGID
and io.processingmodecd = 'P'
and so.usagemnemonic = 'P'
and o.odsaccountid = io.insuranceorgid
and o.accountflg = 'Y') b
set a.accountorgid = b.orgid
where a.careteampatientid = b.patientid
Here is the Merge I also tried
merge into careteampatient a
using (select CTP.CARETEAMPATIENTID patientid, O.ORGANIZATIONID orgid
from acts.careteampatient ctp,
ods.member m,
ods.supplierorganization so,
ods.MASTERSUPPLIERSUPPLIERRELATION mssr,
ods.INSURANCEORGSUPPLIERRELATION IOSR,
ods.INSURANCEORGANIZATION IO,
acts.organization o
where ctp.accountorgid is null
and m.primarymemberplanid = ctp.primarymemberplanid
and SO.AHMSUPPLIERID = M.AHMSUPPLIERID
and mssr.SUPPLIERID = so.SUPPLIERORGID
AND iosr.SUPPLIERID = so.SUPPLIERORGID
AND io.INSURANCEORGID = iosr.INSURANCEORGID
and io.processingmodecd = 'P'
and so.usagemnemonic = 'P'
and o.odsaccountid = io.insuranceorgid
and o.accountflg = 'Y') b
on a.careteampatientid = b.patientid
when matched then
update
set a.accountorgid = b.orgid
This isnt working and Im fresh out of ideas, any help would be awesome. Thanks
Figured it out, I was missing brackets on my ON. It should be on (a.careteampatientid = b.patientid) also my select should read select distinct

Query performance to compare date with many join and entity framework

I have this database model :
I use this query :
public List<Film> ListFilmsSortiesDes7DerniersJoursDVD()
{
DateTime dateDans7Jours = DateTime.Now.AddDays(7);
DateTime dateIlYa7Jours = DateTime.Now.AddDays(-7);
return Query(f => f.Releases.Where(r => r.Langue.langue_code == "FR" && r.TypeRelease.typerelease_code == "DVD").FirstOrDefault().release_date > dateIlYa7Jours
&& f.Releases.Where(r => r.Langue.langue_code == "FR" && r.TypeRelease.typerelease_code == "DVD").FirstOrDefault().release_date < dateDans7Jours && !string.IsNullOrEmpty(f.film_image)).ToList();
}
But the SQL generated have bad performance, about 1.3 seconds to return results (with SQL Server Express 2008 and I already have Index on correct fields):
SELECT [Extent1].[film_id] AS [film_id],
[Extent1].[film_image] AS [film_image],
[Extent1].[film_image_thumb] AS [film_image_thumb],
[Extent1].[film_format] AS [film_format],
[Extent1].[film_motsclefs] AS [film_motsclefs],
[Extent1].[film_nom] AS [film_nom],
[Extent1].[film_nomvf] AS [film_nomvf],
[Extent1].[film_synopsis] AS [film_synopsis],
[Extent1].[film_anneeproduction] AS [film_anneeproduction],
[Extent1].[film_budget] AS [film_budget],
[Extent1].[film_dateajout] AS [film_dateajout],
[Extent1].[film_actif] AS [film_actif],
[Extent1].[utilisateur_id] AS [utilisateur_id],
[Extent1].[film_francais] AS [film_francais],
[Extent1].[film_revenue] AS [film_revenue],
[Extent1].[filmgroupe_id] AS [filmgroupe_id]
FROM [dbo].[Film] AS [Extent1]
OUTER APPLY (SELECT TOP (1) [Filter1].[release_date] AS [release_date]
FROM (SELECT [Extent2].[film_id] AS [film_id],
[Extent3].[release_date] AS [release_date],
[Extent3].[typerelease_id] AS [typerelease_id]
FROM [dbo].[FilmRelease] AS [Extent2]
INNER JOIN [dbo].[Release] AS [Extent3]
ON [Extent3].[release_id] = [Extent2].[release_id]
INNER JOIN [dbo].[Langue] AS [Extent4]
ON [Extent3].[langue_id] = [Extent4].[langue_id]
WHERE N'FR' = [Extent4].[langue_code]) AS [Filter1]
INNER JOIN [dbo].[TypeRelease] AS [Extent5]
ON [Filter1].[typerelease_id] = [Extent5].[typerelease_id]
WHERE ([Extent1].[film_id] = [Filter1].[film_id])
AND (N'CINEMA' = [Extent5].[typerelease_code])) AS [Limit1]
CROSS APPLY (SELECT TOP (1) [Filter3].[release_date] AS [release_date]
FROM (SELECT [Extent6].[film_id] AS [film_id],
[Extent7].[release_date] AS [release_date],
[Extent7].[typerelease_id] AS [typerelease_id]
FROM [dbo].[FilmRelease] AS [Extent6]
INNER JOIN [dbo].[Release] AS [Extent7]
ON [Extent7].[release_id] = [Extent6].[release_id]
INNER JOIN [dbo].[Langue] AS [Extent8]
ON [Extent7].[langue_id] = [Extent8].[langue_id]
WHERE N'FR' = [Extent8].[langue_code]) AS [Filter3]
INNER JOIN [dbo].[TypeRelease] AS [Extent9]
ON [Filter3].[typerelease_id] = [Extent9].[typerelease_id]
WHERE ([Extent1].[film_id] = [Filter3].[film_id])
AND (N'CINEMA' = [Extent9].[typerelease_code])) AS [Limit2]
WHERE ([Limit1].[release_date] > '2013-02-04T00:07:48' /* #p__linq__0 */)
AND ([Limit2].[release_date] < '2013-02-18T00:07:48' /* #p__linq__1 */)
AND ([Extent1].[film_image] IS NOT NULL)
Do you please have any ideas to improve performance of this query ?
Ok why search complicated when the answer is simple :
public List<Film> ListFilmsSortiesDes7DerniersJoursCinema()
{
DateTime dateDans7Jours = DateTime.Now.AddDays(7);
DateTime dateIlYa7Jours = DateTime.Now.AddDays(-7);
return Query(f => f.Releases.Where(r => r.Langue.langue_code == "FR" && r.TypeRelease.typerelease_code == "CINEMA" && r.release_date > dateIlYa7Jours && r.release_date < dateDans7Jours).Any()).ToList();
}
I did a join in too

Resources