Oracle parameter to a inner query - oracle

I'm struggling with an Oracle query. I want to send a value to a inner query but I don't succeed. My query looks as follows:
SELECT * FROM Pro u
LEFT JOIN (SELECT * FROM PROLOG d
WHERE d.Id = (SELECT MAX(Id) FROM PROLOG t
WHERE t.Project = **u.Id**
AND t.Prodstatus IN (5,40)))z ON (u.ID = z.Project)
WHERE u.Id = 22;
I want to replace the u.Id with 22. The value 22 comes from Pro u table. Please give me some hints.

I do not believe you can correlate a join to an inline view, however you can simplify your SQL statement to a simple outer join with a correlated predicate:
SELECT *
FROM pro u
LEFT OUTER JOIN prolog d
ON d.project = u.id
AND d.Id = (SELECT MAX(Id)
FROM prolog t
WHERE t.project = u.id
AND t.prodstatus IN (5,40))
WHERE u.id = 22;

You don't need to pass that value to sub query from Pro table, You can use prolog table value
SELECT * FROM Pro u
LEFT JOIN (SELECT * FROM PROLOG d
WHERE d.Id = (SELECT MAX(Id) FROM PROLOG t
WHERE t.Project = d.Project
AND t.Prodstatus IN (5,40)))z ON (u.ID = z.Project)
WHERE u.Id = 22;

Related

LINQ - Subquery or LEFT OUTER JOIN?

I am trying to optimize my LINQ query performance, and I've noticed a lot of LEFT OUTER JOINs being generated. I know that in SQL, there are some cases in which a single row subquery works better than the equivalent LEFT OUTER JOIN.
For example:
Query 1:
select f.FacilityName, p.Id PatientId, u.DOB, (select u2.NameComputed from adm.Staffs s inner join dbo.AspNetUsers u2 on s.UserId = u2.Id where s.Id = p.StaffId) AssignedTo
from ptn.Patients p
inner join dbo.AspNetUsers u on p.UserId = u.Id
inner join hco.Hcos f on p.HcoId = f.Id
where p.IsRemoved = 0
Query 2:
select f.FacilityName, p.Id PatientId, u.DOB, u2.NameComputed
from ptn.Patients p
inner join dbo.AspNetUsers u on p.UserId = u.Id
inner join hco.Hcos f on p.HcoId = f.Id
left outer join adm.Staffs s on p.StaffId = s.Id
left outer join dbo.AspNetUsers u2 on s.UserId = u2.Id
where p.IsRemoved = 0
Query 1 takes less than a second. Query 2 takes about 45 seconds. If I wanted to make sure LINQ is structured in such a way as to take advantage of this in some cases, how would I go about doing that? That is, is there a way to write a LINQ statement that produces a subquery instead of a LEFT OUTER JOIN?

Hive - how to reuse a sub-query in hive with optimal performance

What is the best way to structure/write a query in Hive when I have a complex sub-query that is repeated multiple times throughout the select statement?
I originally created a temporary table for the sub-query which was refreshed before each run. Then I began to use a CTE as part of the original query (discarding the temp table) for readability and noticed degraded performance. This made me curious about which implementation methods are best with respect to performance when needing to reuse sub-queries.
The data I am working with contains upwards of 10 million records. Below is an example of the query I wrote that made use of a CTE.
with temp as (
select
a.id,
x.type,
y.response
from sandbox.tbl_form a
left outer join sandbox.tbl_formStatus b
on a.id = b.id
left outer join sandbox.tbl_formResponse y
on b.id = y.id
left outer join sandbox.tbl_formType x
on y.id = x.typeId
where b.status = 'Completed'
)
select
a.id,
q.response as user,
r.response as system,
s.response as agent,
t.response as owner
from sandbox.tbl_form a
left outer join (
select * from temp x
where x.type= 'User'
) q
on a.id = q.id
left outer join (
select * from temp x
where x.type= 'System'
) r
on a.id = r.id
left outer join (
select * from temp x
where x.type= 'Agent'
) s
on a.id = s.id
left outer join (
select * from temp x
where x.type= 'Owner'
) t
on a.id = t.id;
There are issues in your query.
1) In the CTE you have three left joins without ON clause. This may cause serious performance problems because joins without ON clause are CROSS JOINS.
2) BTW where b.status = 'Completed' clause converts LEFT join with table b to the inner join though still without ON clause it multiplicates all records from a by all records from b with a where.
3) Most probably you do not need CTE at all. Just join correctly with ON clause and use case when type='User' then response end + aggregate using min() or max() by id:
select a.id
max(case when x.type='User' then y.response end) as user,
max(case when x.type='System' then y.response end) as system,
...
from sandbox.tbl_form a
left outer join sandbox.tbl_formStatus b
on a.id = b.id
left outer join sandbox.tbl_formResponse y
on b.id = y.id
left outer join sandbox.tbl_formType x
on y.id = x.typeId
where b.status = 'Completed' --if you want LEFT JOIN add --or b.status is null
group by a.id

Case based Joins in oracle query

I have below query which returns all the data from inner query including one more field i.e. ctry from tbl_account table.I have used
LEFT JOIN so that even though a_row_id not matched with row_id from tbl_account so that i would still get all the matched data from inner query.
select b.* ,sac.ctry as country from
(SELECT DISTINCT rec.* ,asset.a_row_id
FROM tbl_record rec LEFT JOIN tbl_asset asset
ON asset.from_sn = rec.to_sn
AND asset.from_name = rec.to_productname
AND asset.from_rel = rec.to_rel
LEFT JOIN tbl_country mas
ON rec.loc = mas.a_loc
WHERE rec.cust_id = 2456 ) b
LEFT JOIN tbl_account sac on b.a_row_id = sac.row_id ;
But,now i need to implement case based join in the above query i.e. when a_row_id is not null then inner join with one extra condition will be used and when a_row_id is null left join will be used.
I have tried using CASE statement as below but it is not working and cost of the query is very high as well and I suppose it is because of CASE statement.The
data in all the tables are in millions.
select b.* ,sac.ctry as country from
(SELECT DISTINCT rec.* ,asset.a_row_id
FROM tbl_record rec LEFT JOIN tbl_asset asset
ON asset.from_sn = rec.to_sn
AND asset.from_name = rec.to_productname
AND asset.from_rel = rec.to_rel
LEFT JOIN tbl_country mas
ON rec.loc = mas.a_loc
WHERE rec.cust_id = 2456 ) b
INNER JOIN tbl_account sac
ON CASE
WHEN b.a_row_id IS NOT NULL AND b.a_row_id = sac.row_id and b.from_cn = SAC.to_cn THEN 1
END = 1
LEFT JOIN tbl_account sac
ON CASE
WHEN b.a_row_id IS NULL AND b.a_row_id = sac.row_id THEN 1
END = 1 ;
Is there any other way that i can implement case based joins condition in above oracle query and at the same time cost of query would be less.Is it possible to use decode in this case ? Any help on this would be greatly appreciated.
This syntax is probably what you are looking for:
select b.*, sac.ctry as country
from b
left join tbl_account sac
on b.a_row_id = sac.row_id or (b.a_row_id is null and sac.row_id is null)
where b.from_cn = sac.to_cn or b.a_row_id is null
SQLFiddle

ORA-00979: not a GROUP BY expression while querying a View with a subquery

I have a view as follows - It compiles just fine but when I try to select from it, I get a ORA-00979: not a GROUP BY expression error. If I eliminate the subquery (column 4) from the view, all works fine. Any ideas would be greatly appreciated! Thanks!!
select
l.LAB_GROUP,
l.NAME as LAB,
b.NAME as BENCH,
(select count(distinct s2.SAMPLE_NUMBER)
from SAMPLE s2 inner join TEST t2 on s2.SAMPLE_NUMBER = t2.SAMPLE_NUMBER and t2.STATUS in ('C', 'R') and s2.TEMPLATE <> 'QC_SAMPLE'
inner join LABORATORY_ENTRY le2 on t2.ANALYSIS = le2.ANALYSIS
where s2.LAB_GROUP = l.LAB_GROUP and le2.NAME = l.NAME and t2.X_BENCH = b.NAME and
((select count(t1.TEST_NUMBER)
from TEST t1
where t1.SAMPLE_NUMBER = t2.SAMPLE_NUMBER and t1.ANALYSIS = t2.ANALYSIS and t1.STATUS <> 'R') = 0)) as RFR
from LABORATORY l
inner join LABORATORY_ENTRY le on le.NAME = l.NAME
inner join X_BENCH b on b.NAME = le.X_BENCH
left join (SAMPLE s inner join TEST t on s.SAMPLE_NUMBER = t.SAMPLE_NUMBER and s.STATUS <> 'U'
and s.TEMPLATE <> 'QC_SAMPLE' and t.STATUS in ('I', 'P')) on t.ANALYSIS = le.ANALYSIS and s.LAB_GROUP = l.LAB_GROUP
left join V_LOC_DEPT_FAC ldf on ldf.LOCATION_NUMBER = s.STORAGE_LOC_NO
group by l.LAB_GROUP, l.NAME, b.NAME
If you need to use the group by (which will be the case if you add aggregating functions, but not as the query is currently written) you need to include the subquery in the group by as well. You can add this easiest by adding a SELECT outside your main query and appyling the GROUP BY at that level:
select lab_group, lab, bench, rfr
from
(
select
l.LAB_GROUP as lab_group,
l.NAME as LAB,
b.NAME as BENCH,
(select .....) as RFR
from LABORATORY l
inner join LABORATORY_ENTRY le on le.NAME = l.NAME
inner join X_BENCH b on b.NAME = le.X_BENCH
left join (SAMPLE s inner join TEST t on ...) on
t.ANALYSIS = le.ANALYSIS and
s.LAB_GROUP = l.LAB_GROUP
left join V_LOC_DEPT_FAC ldf on ldf.LOCATION_NUMBER = s.STORAGE_LOC_NO
) x
group by lab_group, lab, bench, rfr
Try removing the...
group by l.LAB_GROUP, l.NAME, b.NAME
As I don't think this is neccesary if you're doing the count within the subquery.
However, for performance reasons I would suggest rewriting your query so that you move the subquery into the FROM section rather than the SELECT one.

Convert SQL select statement to Linq

How can I convert the following SQL select statement to Linq?
SELECT u.Name FROM User u AS DDC
INNER JOIN Country c ON c.UserId = u.UserId
INNER JOIN (
SELECT AddressId,
Address,
PC,
FROM AddressTbl a
WHERE a.CountryId = 1
) AS Addresses ON Addresses.AddressId= u.AddressId
WHERE
u.UserIs = #UserId AND
Addresses.AddressId= #AddressId
Any good reading references?
from u in Users join
c in Country on c.UserId equals u.UserId
join a in Address on a.AddressId equals u.AddressId
where a.CountryId == 1
select u.Name
You can try this out
http://www.sqltolinq.com/

Resources