Aggregation function with the inner join on sql server - sql

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

Related

Pull columns from series of joins in SQL

I am kind of stuck at one problem at my job where I need to pull 2 cols from base table and 1 column from a series of joins.
Please note that, I can not provide real data so I am using dummy column/table names and there are 100s of columns in real project.
Select A.Name,B.Age, D.Sal
From A Left join B on A.iD=B.id and B.Date=CURRENT_DATE
(/* join A and B table and return distinct column which is B.XYZ)
inner join C on C.iD=B.XYZ
(/* join B and C take C.YYY column for next join */)
inner join D on D.id=C.YYY
(/* Take out the D.Sal column from this join */) where A.Dept='IT'
I have written this query but it is taking forever to run because B.XYZ column has a lot of duplicates. how can I get distinct of B.XYZ column from that join.
For Joining Table B, you first get a distinct table of the columns you need from B then join.
SELECT
A.Name,
B.Age,
D.Sal
From A
LEFT JOIN ( -- Instead of all cols (*), just id, Date, Age and xyz might do
SELECT DISTINCT * FROM B
) B ON A.iD = B.id AND B.Date = CURRENT_DATE
--(/* join A and B table and return distinct column which is B.XYZ */)
INNER JOIN C ON C.iD = B.XYZ
--(/*join B and C take C.YYY column for next join */)
INNER JOIN D ON D.id = C.YYY
--(/* Take out the D.Sal column from this join */)
WHERE A.Dept='IT'
You say you get the same rows multifold, because for a b.id, date and age you get the same xyz more than once, or so I understand it.
One option is to join with a subquery that gets the distinct data:
SELECT a.name, b.age, d.sal
FROM a
LEFT JOIN
(
SELECT DISTINCT id, date, age, xyz FROM b
) dist_b ON dist_b.id = a.id and dist_b.date = CURRENT_DATE
INNER JOIN c ON c.id = dist_b.xyz
INNER JOIN d ON d.id = c.yyy
WHERE a.dept = 'IT';
Of course you can even move the date condition inside the subquery:
SELECT a.name, b.age, d.sal
FROM a
LEFT JOIN
(
SELECT DISTINCT id, age, xyz FROM b WHERE date = CURRENT_DATE
) dist_b ON dist_b.id = a.id
INNER JOIN c ON c.id = dist_b.xyz
INNER JOIN d ON d.id = c.yyy
WHERE a.dept = 'IT';
Your LEFT OUTER JOIN doesn't work by the way. As you are inner joining the following tables, a match must exists, so your outer join becomes an inner join. For the outer join to work you would have to outer join the following tables, too.

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.

How to get rows from one or another joined table and then further to more joined tables depending on which first two tables were joined

I have three tables (a, b, c) and two (b and c) need to be joined to get detail data from the first table a. But the problem is that I need to do this in one query.
If I join both tables in the same query than no records are found as detail data is either in b or c, but never in both.
To further complicate things, I need to further join other tables (b2, c2) based on with the record found is from b or c.
I am using MS SQL.
The query I have now is:
select a.*, b.name1, c.name1, b2.url, c2.url
left join b on a.aID = b.aID
left join c on a.aID = c.aID
inner join b2 on b.bID = b2.bID
inner join c2 on c.cID = c2.cID
where a.date > '9/1/2016'
I searched for a few days, but no one seems to need to go after the fourth and fifth tables in the query and so couldn't find any similar answer
Is there any way to do this? Performance is not an issue as the number of records will be less than 1,000 after executing a where clause that will always limit the records from table a.
A series of left joins with inner joins as subqueries should do the trick. The subqueries pull the b/b2 and c/c2 data together for reference in the left joins with a:
select a.*, b.name1, c.name1, b2join.url, c2join.url
FROM a
LEFT JOIN b
on a.aID = b.aID
LEFT JOIN c
on a.aID = c.aID
LEFT JOIN
(SELECT b.aID, b.bID, b2.url
FROM b
INNER JOIN b2
on b.bID = b2.bID) as b2join
on b2join.aID = a.aID
LEFT JOIN
(SELECT c.aID, c.cID, c2.url
FROM c
INNER JOIN c2
on c.cID = c2.cID) as c2join
on c2join.aID = a.aID
I think a Left Join will do it, at least for the first part:
select a.*, b.name1, c.name1
left join b on a.aID = b.aID
left join c on a.aID = c.aID
where a.date > '9/1/2016'
You will get c.name1 null when data is in b table, and b.name1 will be null when data is in c table.
For the other two joins and not sure but left join could also work.
I think, it is more simple and brief way to get the same result:
select a.*, b.name1, c.name1, b2join.url, c2join.url
FROM a
LEFT JOIN b on a.aID = b.aID
LEFT JOIN c on a.aID = c.aID
LEFT JOIN b as b2join on b2join.bID = b.bID
LEFT JOIN a as c2join on c2join.cID = c.cID

What is wrong with the following SQL left join?

I have 5 tables: A, B, C, D, E
A: {ID, Value, GroupID, FilterID, In_Date}
B: {ID, Description, Out_Date, From_Date }
C: {ID, Category}
D: {GroupID, GroupName}
E: {FilterID, FilterName}
There could be missing IDs in B and C as a result, I'm trying to do a LEFT JOIN to get the required info. In my dataset, I've explicitly added a row in A with ID that's not in B or C. I expect it to be picked up in the following query, but it doesn't happen. I believe I'm going wrong in the WHERE clause due to null values in B and C.
SELECT A.Value, A.Group, B.Description, C.Category, D.GroupName, E.FilterName
FROM A LEFT JOIN B ON A.ID = B.ID
LEFT JOIN C ON A.ID = C.ID,
D,E
WHERE
B.Out_Date>A.In_Date,
A.GroupID=D.GroupID,
A.FilterID=E.FilterID
How can I fix this to retrieve the fields I want with null values when the ID is not in B or C , but in A?
1) Don't mix old comma separated join syntax with modern explicit join syntax!
2) When left join, put the right side table's conditions in the ON clause to get true left join behavior. (When in WHERE you get inner join result.)
SELECT A.Value, A.Group, B.Description, C.Category, D.GroupName, E.FilterName
FROM A LEFT JOIN B ON A.ID = B.ID AND B.Out_Date > A.In_Date
LEFT JOIN C ON A.ID = C.ID
JOIN D ON A.GroupID = D.GroupID
JOIN E ON A.FilterID = E.FilterID
Value and Group are reserved words in ANSI SQL, so you may need to delimit them, as "Value" and "Group".
First point: You shouldn't mix join syntaxes, just use explicit syntax.
Because of your where clause, you effectively turn your left joins in inner joins. You are probably looking for:
SELECT A.Value, A.Group, B.Description, C.Category, D.GroupName, E.FilterName
FROM A
LEFT JOIN B
ON A.ID = B.ID
AND B.Out_Date > A.In_Date
LEFT JOIN C
ON A.ID = C.ID
INNER JOIN D
ON A.GroupID = D.GroupID
INNER JOIN E
ON A.FilterID = E.FilterID
You can use this query for your problem.
SELECT A.Value, A.Group, B.Description, C.Category, D.GroupName, E.FilterName
FROM A
LEFT JOIN B
ON A.ID = B.ID
AND B.Out_Date > A.In_Date
LEFT JOIN C
ON A.ID = C.ID
LEFT JOIN D
ON A.GroupID = D.GroupID
LEFT JOIN E
ON A.FilterID = E.FilterID
Here is your table details
A: {ID, Value, GroupID, FilterID, In_Date}
B: {ID, Description, Out_Date, From_Date }
C: {ID, Category}
D: {GroupID, GroupName}
E: {FilterID, FilterName}
now you try to retrieve data using left join
so you try the flowing script
SELECT A.Value, A.Group, B.Description, C.Category, D.GroupName,E.FilterName from A left join B on A.ID=B.ID
left Join C on A.ID=C.ID
Left Join D on A.GroupID=D.GroupID
Left Join E on A.FilterID=E.FilterID
where B.Out_Date>A.In_Date
I hope this is help full for you.

Bringing data from Multiple tabel using Left outer Join

I have 4 tables , A,B,C,D.
A stores my Customer Id , B ,C D stores various details of customer.
For Eg. B stores Education ,C stores Occupation , D stores Interests.
Now a Customer may have not have entry in C ,D or It may have entry in B and D but not in C.
I want to select all the information by joing all the four tables. Customer_id is present in all the four tables. Inner join will clearly not work.
I am thinking of Left outer join. Could someone help me with the requirement.
An LEFT OUTER JOIN will only get the rows where column A:B match or B:C match, if u want to keep the values of certain rows from table C, D in blank u can first make an
LEFT OUTER JOIN WITH A and B and then make a full outer join with C and D, in that way u are going to be able to keep all the data from C and D no mather if the have or not values in it
I am thinking in somethin like this:
SELECT a.store, b.education, d.storeinterest FROM
(
SELECT * FROM A
LEFT OUTER JOIN B
ON A = B
) A
FULL OUTER JOIN C
ON A = C
FULL OUTER JOIN D
ON A= D
Something along these lines should get you started:
SELECT a.*, b.*, c.*, d.*
FROM a LEFT OUTER JOIN b on
a.customer_id = b.customer_id LEFT OUTER JOIN c
on a.customer_id = c.customer_id LEFT OUTER JOIN d
on a.customer_id = d.customer_id