How I can retrieve all records with 1-2 queries using regular SQL and Linq-To-Entities? - sql

I uploaded simplified SQL ERD on Picasa.
I tried to do it but I manage to it with more than 2 queries.
I need to retrieve all records from table D with specific E_Id of table E and specific TypeId of table A
UPDATED: I need also that all records from B that mapped to TypeId will be alse retrieved even if not all of them are mapped in table C (some kind of LEFT-RIGHT JOIN)
I need to do it at most 2 queries and then convert it to Linq-To-Entites statement
If it can be done with 1 query I prefer with 1 query
Thank you

SQL query:
SELECT D.*
FROM D
INNER JOIN C ON C.Id = D.C_Id
INNER JOIN B ON B.Id = C.B_Id
INNER JOIN A ON A.Id = B.A_Id
WHERE D.E_Id = #eId AND A.TypeId = #typeId
SELECT B.*
FROM B
INNER JOIN A ON A.Id = B.A_Id
WHERE A.TypeId = #typeId
Linq directly (if navigation properties don't exists):
var query = from d in context.D
join c in context.C on c.Id equals d.cId
join b in context.B on b.Id equals c.bId
join a in context.A on a.Id equals b.aId
where d.eId == eId && a.TypeId == typeId
select d;
var query2 = from b in context.B
join a in context.A on a.Id equals b.aId
where a.TypeId == typeId
select b;
Linq if navigation properties are correctly set up:
var query = from d in context.D
where d.E.Id == eId &&
d.C.B.A.TypeId == typeId
select d;
var query2 = from b in context.B
where b.A.TypeId == typeId
select b;

Any reason why the below won't work for you?
SELECT D.*
FROM D
INNER JOIN C
ON C.Id = D.C_Id
INNER JOIN B
ON B.Id = C.B_Id
INNER JOIN A
ON A.Id = B.A_Id
WHERE D.E_id = <The E_Id> AND A.Typeid = <The Typeid>

Related

Aggregation function with the inner join on sql server

I have 5 tables (A,B,C,D). All are inner joined and used to display data. Another table E has the column sourceId which has reference in column A. I need to show the count of occurrence in the main query. For example:
A.*,B.*,C.*,D.*
FROM A
INNER JOIN B
ON A.BId= B.Id
INNER JOIN C
ON A.CId = C.Id
INNER JOIN D
ON A.Did= D.Id
E table can contain 2 or 1 or 0 records referencing to table A. I need to display count of the occurrence in the above query and sort accordingly from 0 to 2. Can some one help me writing this up? I am not sure how should I go ahead with aggregation function over here.
Output should look like this:
E.Count|A.*|B.*|C.*|D.*|
Something like this:
select A.*,B.*,C.*,D.*,E_count
FROM A
INNER JOIN B ON A.BId= B.Id
INNER JOIN C ON A.CId = C.Id
INNER JOIN D ON A.Did= D.Id
outer apply (
select count(*) as E_count
from E
where E.sourceId = A.Id
) E
or
select A.*,B.*,C.*,D.*,E_count
FROM A
INNER JOIN B ON A.BId= B.Id
INNER JOIN C ON A.CId = C.Id
INNER JOIN D ON A.Did= D.Id
left join (
select count(*) as E_count
from E
group by E.sourceId
) E on E.sourceId = A.Id

Access SQL - Joins on multple tables

I have come across a Join Error in Access SQL, when using multiple "ON" criteria's. I am unable to perform an ON clause on 2 different tables, for example:
select *
from
(((A
left join B on a.id = b.id)
left join c on c.id = b.id)
left join D
on (d.id = b.id) and (d.id = a.id)
That final join statement causes an error because I link table D on table B first, and then link Table D on Table A. If I choose to instead link table D on Table B again, then it resolves. However, I need to join it this way due to the certain data I need to link Table D on from both tables.
How can I more efficiently structure my query to achieve my results?
you may try this select * from A left join B on a.id = b.id left join c on c.id = b.id left join D on d.id = b.id and d.id = a.id
It's somewhat difficult to tell what you're trying to do exactly, but most likely, this is what you want:
select *
from
(((A
left join B on a.id = b.id)
left join C on c.id = b.id)
left join D on d.id = a.id)
Since you're trying a LEFT JOIN, there is no reason to link multiple ids to eachother.

JOIN on column only if NOT NULL

I'm in the process of re-writing an old SQL query and have troubles making sense out of it. It contains several conditions of the form
SELECT ...
FROM a, b, c
WHERE
c.id = ...
AND (
a.x_id IS NULL
OR a.x_id = c.x_id
)
AND b.id = a.b_id (+)
Can this query be rewritten using proper JOIN syntax? Is it equivalent to the following or will it produce different results under certain circumstances?
SELECT ...
FROM b
LEFT JOIN a
ON b.id = a.b_id
LEFT JOIN c
ON a.x_id = c.x_id
WHERE c.id = ...
The original query is 100 lines long and spans 5 tables, plus several joins over "virtual tables" (i.e. where conditions of the form x.z_id = y.z_id), which makes it hard to break down into more manageable bits or debug.
if you want same result as you have in first query - you must make left join only with table a, like this :
SELECT ...
FROM b, c
LEFT JOIN a
ON b.id = a.b_id and b.id = a.b_id
WHERE
c.id = ... b.c_id
or if you want the same style with all tables, you can use inner join with table b, like this :
SELECT ...
FROM c
INNER JOIN b
on b.c_id = c.id
LEFT JOIN a
ON b.id = a.b_id
WHERE
c.id = ...
in my both query we select data from table b where column is not null

Stuck on multiple table filtering query

Ok so I will try to simplify the problem that I have.
I have 4 tables:
TableA:
OneID
TableB:
OneID (FK to TableA)
TwoID (FK to TableC)
TableC:
TwoID
ThreeID (FK to TableD)
TableD:
ThreeID
I need a query to retrieve data from all 4 of these tables.
The query criteria is:
want to inner join tables A, B, C
want to join above result with table D with the following conditions:
if a record is in Table D but not in Table C, then it must always be present in the results
otherwise if a record is in Table D and Table C, then it should only be present if it is in the result of the A,B,C join
The scenario you have described is not really possible (or at least they are not really logical)
if a record is in Table D but not in Table C, then it must always be present in the results
The only way a record could be "in Table D and not in Table C" is if the foreign key is null in table D, with no link from table D to tables A or B there is no other way you could define a record as being present in D and not in C:
otherwise if a record is in Table D and Table C, then it should only be present if it is in the result of the A,B,C join
Again, the only way this could happen is with NULLABLE foreign keys. Regardless I think any of the below will get you the results you require:
SELECT A.OneID, B.TwoID, c.ThreeID, D.FourID
FROM D
LEFT JOIN (C
INNER JOIN B
ON B.TwoID = C.TwoID
INNER JOIN A
ON A.OneID = B.OneID)
ON C.ThreeID = D.ThreeID;
Or
SELECT A.OneID, B.TwoID, c.ThreeID, D.FourID
FROM A
INNER JOIN B
ON B.OneID = A.OneID
INNER JOIN C
ON C.TwoID = B.TwoID
RIGHT JOIN D
ON D.ThreeID = C.ThreeID
Or
SELECT A.OneID, B.TwoID, c.ThreeID, D.FourID
FROM A
INNER JOIN B
ON B.OneID = A.OneID
INNER JOIN C
ON C.TwoID = B.TwoID
INNER JOIN D
ON D.ThreeID = C.ThreeID
UNION ALL
SELECT NULL, NULL, NULL, FourID
FROM D
WHERE ThreeID IS NULL;
Examples on SQL Fiddle
The first two have the same execution plan, it is just a matter of preference, I personally dislike using RIGHT JOIN because it makes queries feel like they in the wrong order i.e bottom to top, but this is purely my preference. The last query may perform better depending on the cardinality of your data and any indexes you have
EDIT
With your revised criteria I think the easiest way to implement this is with a UNION ALL:
SELECT A.OneID, B.TwoID, c.ThreeID, d3 = D.ThreeID
FROM A
INNER JOIN B
ON B.OneID = A.OneID
INNER JOIN C
ON C.TwoID = B.TwoID
INNER JOIN D
ON D.ThreeID = C.ThreeID
UNION ALL
SELECT NULL, NULL, NULL, ThreeID
FROM D
WHERE NOT EXISTS (SELECT 1 FROM C WHERE C.ThreeID = D.ThreeID);
Example on SQL Fiddle
I am not 100% sure I understood you correctly but I will try to help anyway. It seems that you need to do FULL OUTER JOIN on table D:
SELECT
*
FROM
TableA AS A INNER JOIN
TableB AS B ON B.A_Id = A.Id INNER JOIN
TableC AS C ON C.B_Id = B.Id FULL OUTER JOIN
TableD AS D ON D.C_Id = C.Id
If I have misunderstood your requirements and you need more complicated criteria, you could just do FULL OUTER JOIN on all the tables and put extra conditions in WHERE part:
SELECT
*
FROM
TableA AS A FULL OUTER JOIN
TableB AS B ON B.A_Id = A.Id FULL OUTER JOIN
TableC AS C ON C.B_Id = B.Id FULL OUTER JOIN
TableD AS D ON D.C_Id = C.Id
WHERE
--if a record is in Table D but not in Table C, then it must always be present in the results
(D.Id IS NOT NULL AND C.Id IS NULL) OR
(
--otherwise if a record is in Table D and Table C, then it should only be present if it is in the result of the A,B,C join
(D.Id IS NOT NULL AND C.Id IS NOT NULL) AND
--want to inner join tables A, B, C
(A.Id IS NOT NULL AND B.Id IS NOT NULL AND B.Id IS NOT NULL)
)

How to update with inner join in Oracle

Could someone please verify whether inner join is valid with UPDATE statment in PL SQL?
e.g.
Update table t
set t.value='value'
from tableb b inner join
on t.id=b.id
inner join tablec c on
c.id=b.id
inner join tabled d on
d.id=c.id
where d.key=1
This synthax won't work in Oracle SQL.
In Oracle you can update a join if the tables are "key-preserved", ie:
UPDATE (SELECT a.val_a, b.val_b
FROM table a
JOIN table b ON a.b_pk = b.b_pk)
SET val_a = val_b
Assuming that b_pk is the primary key of b, here the join is updateable because for each row of A there is at most one row from B, therefore the update is deterministic.
In your case since the updated value doesn't depend upon another table you could use a simple update with an EXIST condition, something like this:
UPDATE mytable t
SET t.VALUE = 'value'
WHERE EXISTS
(SELECT NULL
FROM tableb b
INNER JOIN tablec c ON c.id = b.id
INNER JOIN tabled d ON d.id = c.id
WHERE t.id = b.id
AND d.key = 1)
update t T
set T.value = 'value'
where T.id in (select id from t T2, b B, c C, d D
where T2.id=B.id and B.id=C.id and C.id=D.id and D.key=1)
-- t is the table name, T is the variable used to reffer to this table