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 (+)
Related
I have two tables in my PostgreSQL database (Table A and Table B). Both of these tables have a createdAt column. I want to do a full join on these two tables and then sort the result based on createdAt values on both A and B tables. Below is an example of what I want to be my query result.
Table A
colA joinColumnA createdAtA
----- ----------- ---------
a1 1 2014
a2 2 2019
a3 3 2020
Table B
colB, joinColumnB createdAtB
--- ---------- -----------
b1 2 2013
b2 4 2015
b3 5 2016
Result
colA, joinColumnA createdAtA colB joinColumnB createdAtB
---- ----------- ----------- ---- ----------- -----------
a3 3 2020 null null null
a2 2 2019 b1 2 2013
null null null b3 5 2016
null null null b2 4 2015
a1 1 2014 null null null
You can ORDER BY GREATEST(createdAtA, createdAtB):
SELECT *
FROM tableA
FULL JOIN tableB
ON tableA."joinColumnA" = tableB."joinColumnB"
ORDER BY GREATEST("createdAtA", "createdAtB") DESC;
colA
joinColumnA
createdAtA
colB
joinColumnB
createdAtB
a3
3
2020
a2
2
2019
b1
2
2013
b3
5
2016
b2
4
2015
a1
1
2014
View on DB Fiddle
You could try using the union for max createdAT for join column in left joinwitn the two table adn order by ifnull(createdAtA, createdAtB)
select colA, joinColumnA, createdAtA, null colB, null joinColumnB, null createdAtB
from (
select joinColumn, max(createdAt)
from (
select joinColumnA joinColumn, createdAtA createdAt
from tableA
select joinColumnB , createdAtB
from tableB
) t1
group by joinColumn
) t2
left join tableA ON tableA.joinColumnA = t2.joinColumn
left join tableB ON tableB.joinColumnA = t2.joinColumn
order by nullif(createdAtA, createdAtB)
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
Say I have a table, called tablex, as follows:
name|year
---------
Bob | 2010
Mary| 2011
Sam | 2012
Mary| 2012
Bob | 2013
Names appear at most twice. I want to remove from the table only those names that are repeated and have a difference of one year (in which case I want to keep the newer year).
name|year
---------
Bob | 2010
Sam | 2012
Mary| 2012
Bob | 2013
I have tried:
SELECT a.Name, a.Year, b.Year
FROM tablex AS a
LEFT JOIN tablex AS b
ON a.Name=b.Name AND (a.Year=b.Year OR b.Year-a.Year=1)
ORDER BY a.Name, a.Year
results in:
Name YearA YearB
1 Bob 2010 2010
2 Bob 2013 2013
3 Mary 2011 2011
4 Mary 2011 2012
5 Mary 2012 2012
6 Sam 2012 2012
Bob's and Sam's entries are correct, how can I restrict it further to only include Mary 2012 2012?
From the question is not clear if you want to SELECT (suppressing the duplicates) or actually DELETE the "duplicates". The select case:
SELECT a.Name, a.Year
FROM tablex AS a
WHERE NOT EXISTS (
SELECT * FROM tablex AS b
WHERE b.Name = a.Name
AND b.Year = a.Year +1
);
And the delete case:
DELETE
FROM tablex AS a
WHERE EXISTS (
SELECT * FROM tablex AS b
WHERE b.Name = a.Name
AND b.Year = a.Year +1
);
DELETE FROM tablex t
WHERE year + 1 =
(SELECT MAX(year)
FROM tablex
WHERE name = t.name)
Or, if you don't want to delete anything, but want a query to only give the desired results:
SELECT *
FROM tablex t
WHERE year + 1 !=
(SELECT MAX(year)
FROM tablex
WHERE name = t.name)
you can use :
SELECT a.Name, a.Year, b.Year
FROM tablex AS a
LEFT JOIN tablex AS b
ON a.Name=b.Name AND (a.Year=b.Year )
ORDER BY a.Name, a.Year
This operation deletes rows from the table where the same name with a newer year also exist:
delete from tablex t1 where year < (select max(year) from tablex where name = t1.name)
OK, so in MS Access I am trying to join two tables on two fields (customer ID and product type), have table A use a sum of each product type, and have all the records from table A so I can know what is missing from table B.
In table A, there are multiple records for each customer for each product type by year. But in table B there is only one record per product type. And in table B not all the product types are there.
Example Tables:
Table A:
Cust ID ProdType Year Number
1 A 2014 5
1 A 2013 8
1 B 2014 3
2 A 2014 13
2 C 2014 2
3 B 2014 1
3 C 2014 4
Table B:
Number
Cust ID ProdType Arrived
1 A 5
2 A 13
2 C 2
3 B 1
3 C 2
Final Result should look like:
Sum of Number
Cust ID ProdType Number Arrived
1 A 13 5
1 B 3
2 A 13 13
2 C 2 2
3 A 1 1
3 C 4 2
Try this,
MySQL Syntax
select a.cust_id, a.prodtype, sum(a.number), b.arrived
from table_a a left join table_b b on a.cust_id=b.cust_id and a.prodtype=b.prodtype
group by a.cust_id, a.prodtype
Here is DEMO (MySQL)
Ms-Access
select a.cust_id, a.prodtype, sum(a.number), b.arrived
from table_a a left join table_b b
on a.cust_id=b.cust_id and
on a.prodtype=b.prodtype
group by a.cust_id, a.prodtype
I have two tables, students and school_year.
students
---------
ID Name
---------
1 ABC
2 XYZ
school_year
-----------
ID student_id grade year
--------------------------
1 1 5 2011
2 1 6 2012
3 2 1 2010
4 2 2 2011
5 2 3 2012
I join them and get this result
select s.*, sy.grade, sy.year
from students s
left join school_year sy
on s.id=sy.student_id
order by s.name
and I get this result
id name grade year
---------------------------
1 ABC 5 2011
1 ABC 6 2012
2 XYZ 1 2010
2 XYZ 2 2011
2 XYZ 3 2012
I would like to join school year table where grade is maximum/highest for the student so the table would look like this.
id name grade year
-------------------------
1 ABC 6 2012
2 XYZ 3 2012
Please help. Thanks.
Try this out:
SELECT s.id, s.name, sy1.grade, sy1.year FROM school_year sy1
LEFT JOIN school_year sy2
ON sy1.student_id = sy2.student_id AND sy1.grade < sy2.grade
JOIN students s ON sy1.student_id = s.id
WHERE sy2.grade IS NULL
Fiddle here.