I'm struggling to write an query to join tables in oder to get required results
Basically I have 4 tables
1)
ID
Date
123
2020
123
2021
456
2022
456
2021
2)
id
fulldate
id2
year
123
102021
xyz
2020
123
102020
xyz
2021
456
102021
abc
2021
456
102022
abc
2022
3)
id3
fulldate
id2
year
w12
102021
xyz
2020
w12
102020
xyz
2021
a12
102021
abc
2021
a12
102022
abc
2022
4)
id4
fulldate
id3
year
1990
102021
w12
2020
1990
102020
w12
2021
2060
102021
a12
2021
2060
102022
a12
2022
I would like to get ID and ID4 as result for date 2021
Thus I would like to get:
ID
ID4
123
1990
456
2060
My query :
Select a.ID, d.ID4
from table1 as a
left join table2 as b on a.id = b.id and a.date = b.year
inner join table3 as c on b.id2 = c.id2 and b.fulldate = c.fulldate
inner join table4 as d on c.id3 = d.id3 and c.fulldate = d.fulldate
where b.year = '2021'
I changed your LEFT JOIN to an INNER JOIN but that shouldn't have impacted your result. The code you provided matches the desired output, so double check your database table structure and query to ensure it matches what you provided us.
SQL:
SELECT
a.ID,
d.ID4
FROM
table1 a
INNER JOIN table2 b ON a.id = b.id
AND a.date = b.year
INNER JOIN table3 c ON b.id2 = c.id2
AND b.fulldate = c.fulldate
INNER JOIN table4 d ON c.id3 = d.id3
AND c.fulldate = d.fulldate
WHERE
b.year = '2021'
Results:
| ID | ID4 |
|-----|------|
| 123 | 1990 |
| 456 | 2060 |
Related
I want to join few tables:
table1:
A B_key B_version C D
123 abc 1 ccc 11
123 abc 2 ddd 11
456 dfg 1 rrr 22
789 vvv 1 55
table2:
A E F
123 s 5
456 r
111 t 2
table3:
B_key B_version G
abc 1 aa
abc 1 bb
abc 2 aa
abc 2 cc
dfg 1 aa
so the result would look like this:
A B_key B_version C D E F G
123 abc 1 ccc 11 s 5 aa
123 abc 1 ccc 11 s 5 bb
123 abc 2 ddd 11 s 5 aa
123 abc 2 ddd 11 s 5 cc
456 dfg 1 rrr 22 r aa
789 vvv 1 55
Version can go as high as 8.
IF I don't have A, B_key or B_version - the line is useless. Otherwise I need to keep all the information I do have.
In reality I have many more columns.
I've tried:
SELECT table1.A, table 1.B_key, table 1.B_version, table 1.C, table 1.D,
table2.E, table2.F,
table3.G
FROM table1
LEFT JOIN table2
ON table1.A = table2.A
LEFT JOIN table3
ON table1.B_key = table3.B_key AND
table1.B_version = table3.B_version
and the same with FULL JOIN.
It ends up the same: for every B_key only the highest B_version is kept, while the others disappear.
How can I avoid loosing information?
You can use left joins among tables as below :
select t1.A, t1.B_key, t1.B_version, t1.C, t1.D, t2.E, t2.F, t3.G
from table1 t1
left join table2 t2 on t2.A = t1.A
left join table3 t3 on t3.B_key = t1.B_key and t3.B_version = t1.B_version
Demo
in order to bring also the rows for unmatched values for join conditions.
If I understand correctly, you want all the b_keys and b_versions from table1 and table3. Then you want to bring in the other data. That suggests left joins
select . . .
from ((select B_key, B_version
from table1
) union -- on purpose to remove duplicates
( select B_key, B_version
from table3
)
) bb left join
table1 t1
on t1.b_key = bb.b_key and
t1.b_version = bb.b_version left join
table2 t2
on t2.a = t1.a left join
table3 t3
on t1.b_key = bb.b_key and
t1.b_version = bb.b_version;
I'm trying to join 2 different data sets with different columns and when I make the join I get repeated results.
My input dataset1 with actual data:
Cust_id Year sales
----------------------
1 2016 679862
1 2017 705365
1 2018 195662
1 2019 201234
2 2016 51074
2 2017 50611
2 2018 19070
2 2019 20123
My input dataset2 with estimated data:
Cust_id Year salesest
-------------------------
1 2018 779862
1 2019 125662
2 2017 23456
2 2018 32856
2 2019 26602
Desired output:
Cust_id Year sales salesest
-------------------------------
1 2016 679862 null
1 2017 705365 null
1 2018 195662 779862
1 2019 201234 125662
2 2016 51074 null
2 2017 50611 23456
2 2018 19070 32856
2 2019 20123 26602
This is what I have tried:
select
a.*, b.salesest
from
tab1 a, tab2 b
where
a.Cust_id = b.Cust_id
You want a LEFT JOIN. The correct syntax is:
select a.*, e.salesest
from actuals a left join
estimates e
on a.Cust_id = e.Cust_id and
a.year = e.year;
you also need to specify the year - and make an outer join for the times when there is no corresponding year in the other table.
select a.*, b.salesest
frpm tab1 a, tab2 b
where
a.Cust_id=b.Cust_id
AND a.YEAR = b.YEAR (+)
Well, I have the following table (Table1):
------------------------------------
GroupID oDate oDesc
------------------------------------
1 2016-05-01 A
2 2016-05-20 B
3 2017-03-01 C
4 2017-03-28 D
Then I have the following table (Table2):
------------------------------------
AutoID GroupID oItem
------------------------------------
1 1 abc
2 1 def
3 2 ghi
4 2 jkl
5 3 mno
6 4 pql
I want to know all oItem in Table2 that has a link to Table1 in a same year. The result should be like this:
---------------------------
oYear oItem
---------------------------
2016 abc
2016 def
2016 ghi
2016 jkl
2017 mno
2017 pql
Is there any idea how to do this? Thank you.
You can just use inner join to get the desired result.
select datepart(yyyy, t1.odate) as oyear, t2.oitem
from table1 t1
inner join table2 t2 on t1.groupid = t2.groupid
Use Year inbuilt function to extract year from date column. Try this
select Year(Odate) as Oyear,B.oItem
from table1 A inner join table2 B
on A.GroupID = B.GroupID
I have three tables with the following structures:
User Table
UserID Name Age
------ ---- ---
001 AA 23
002 BB 25
003 CC 30
004 DD 24
005 EE 23
temp_User Table
UserID Name Age
------ ---- ---
001 AA 23
002 BB 25
004 DD 24
005 EE 23
007 GG 23
009 HH 28
ExceptionUsers Table
UserID Status
------ --------
021 Active
002 Inactive
004 Active
010 Active
012 Inactive
I used the following query to retrieve my result:
Query
select
A.Name
,B.Name
,A.Age
,B.Age
from User A
inner join temp_User B
on A.UserID = B.UserID
left join ExceptionUsers C
on A.UserID = C.UserID
and C.Status = 'Inactive'
order by
A.Name
Result
001 AA 23
002 BB 25
005 EE 23
But the result includes users who are 'Active'.
001 AA 23
002 BB 25
004 DD 24
005 EE 23
How can I try the query to get my result?
Move C.Status = 'Inactive' to the where clause.
I'd move the LEFT JOIN logic to the WHERE clause, to a NOT EXISTS.
select A.Name, B.Name, A.Age, B.Age
from User A
inner join temp_User B
on A.UserID = B.UserID
where not exists (select * from ExceptionUsers C
where A.UserID = C.UserID
and C.Status = 'active')
order by A.Name
Left join does not filter the data provided on joining condition.
So you may move the joining condition and C.Status = 'Inactive' to where clause and it treats as inner join
select A.Name, B.Name, A.Age, B.Age
from User A
inner join temp_User B
on A.UserID = B.UserID
left join ExceptionUsers C
on A.UserID = C.UserID
where
C.Status = 'Inactive'
order by A.Name
you can use the below query to get the list of active user with their details.
select * from temp_User where UserID in (select UserID from ExceptionUsers where Status = 'Inactive')
If I want to display Order_Number data1 data2 data3 (most current by date changed OtherData1, OtherData2, OtherData3) date_changed the problem is I wasn't just one line, I was getting multiple lines for each order number.
What I would love to get is
1, a, f,q, cc,ccc,abc, 12/2/2014, bob
3, c, b,h, aa,aaa,abc, 12/2/2014, bob
Thanks!
I was working with
SELECT
t.Order_Number,
cr.data1, cr.data2, cr.data3,
t.OtherData1, t.OtherData2, t.OtherData3,
x.date_changed, cr.name
FROM
(SELECT
Order_Number,
Max(date_changed) as date_changed
FROM
table2
GROUP BY
Order_Number) x
JOIN
table2 t ON x.date_changed = t.date_changed
LEFT JOIN
table1 cr ON x.Order_Number = cr.Order_Number
WHERE cr.name = 'bob'
Here are example tables.
Table1:
Order_Number data1 data2 data3 name
1 a f q bob
2 b g g john
3 c b h bob
4 d s j john
Table2:
Order_Number date_changed OtherData1 OtherData2 OtherData3
1 11/30/2014 aa aaa abc
1 12/1/2014 bb bbb def
1 12/2/2014 cc ccc abc
3 12/1/2014 dd aaa def
2 11/30/2014 dd bbb abc
2 12/1/2014 ss ccc def
3 12/2/2014 aa aaa abc
4 11/26/2014 fc wer wsd
Your Join to config_log (Table2) needs to include the entire composite key if you want to retrieve unique rows.
JOIN
conf_log t ON x.date_changed = t.date_changed
And x.Order_Number = t.Order_number
I think you need to have 2 sub querys:
SELECT
Data.Order_Number,
Data.data1, Data.data2, Data.data3,
Data.OtherData1, Data.OtherData2, Data.OtherData3,
Data.date_changed, Data.name
FROM
(SELECT
Order_Number,
Max(date_changed) as date_changed
FROM
table2
GROUP BY
Order_Number) x
JOIN (SELECT
t.Order_Number,
cr.data1, cr.data2, cr.data3,
t.OtherData1, t.OtherData2, t.OtherData3,
t.date_changed, cr.name
FROM table2 t
JOIN table1 cr
ON t.Order_Number = cr.Order_Number) AS Data
ON x.date_changed = data.date_changed
AND x.Order_Number = data.Order_number
WHERE cr.name = 'bob'
The fact that you had cr.name in the where clause means the LEFT JOIN had the same affect as just JOIN.