MySQL Table merge / union? - mysql

I have 2 tables. The first one is refreshed daily.(This table has more that 10 columns but 2 of those is relevant) I would like to make a daily statistics from vid (which is a unique id ) and population. New vid ID-s can appear and disappear every day. For example :
1st day :
vid population
123 456
124 567
345 1024
2nd day :
vid population
123 470
124 520
344 100
The second table will be the statistics, and i would like the following result :
|--------------------1st day data
| |----------- 2nd day data
vid stat0819 stat0820
123 456 470
124 567 520
344 0 100
345 1024 0
Is it possible with one SQL query? I think, the UNION is the key, but I can't figure it out how.

Is this maybe what you are looking for ?
select tbl1.vid, tbl1.population as tbl1_population, tbl2.population as tbl2_population
from tbl1
left join tbl2 on tbl2.vid = tbl1.vid
union
select tbl2.vid, tbl1.population as tbl1_population, tbl2.population as tbl2_population
from tbl1
right join tbl2 on tbl2.vid = tbl1.vid;

Related

Joining tables while using group by in SQL

I have two tables to join in SQL using the ID column in both. Table 1 has only unique values of ID as follows and I want to keep all columns of this table:
ID code 1 code 2
1 123 99
2 222 09
3 344 13
Table 2 has multiple rows of each ID as follows:
ID application_time Application Number
1 11jan2004 123
2 15oct2010 124
1 24nov2008 845
3 05sep2010 166
1 07feb2001 865
2 24aug2017 545
3 12mar2009 233
2 11dec2001 811
So, from table 2, I want to add the total count of each ID, and Min and Max of Application_time to table 1. I also need to count the number Application Numbers that start with 8. of I do not know where I should use group by (). So the outcome should look like:
ID code 1 code 2 count Min (application_time) Max (application_time)
1 123 99 3 07feb2001 24nov2008
2 222 09 3 11dec2001 24aug2017
3 344 13 2 12mar2009 05sep2010
Count of Application Number starting with 8
2
1
0
here is how you can do it:
select
t1.Id
,t1.code1
,t1.code2
, count(*) count
,min(application_time)
,max(application_time)
, sum( case when left( t2.application number, 1 ) = '8' then 1 else 0 end )
from table1 t1
join table2 t2
on t1.Id = t2.Id
group by
t1.Id
,t1.code1
,t1.code2

MySQL Cumulative Total

A company rewards one of its employees every day. The data is maintained in a table called REWARDS. As shown in the sample data below, we have one row per day in the table with the following structure:
(Sorry for the poor table formatting)
REWARD_DATE EMP_ID REWARD_AMT
1-Jan-15 101 400
2-Jan-15 102 300
3-Jan-15 101 700
4-Jan-15 102 500
5-Jan-15 103 100
Can you write a query to report the running totals as the following?
REWARD_DATE #EMP TOT_REWARD_AMT
1-Jan-15 1 400
2-Jan-15 2 700
3-Jan-15 2 1400
4-Jan-15 2 1900
5-Jan-15 3 2000
You could do this (slightly simplified now):
SELECT b.rdate, COUNT(distinct a.eid) empcnt, SUM(a.amnt) total
FROM tbl a
INNER JOIN tbl b ON b.rdate>=a.rdate
GROUP BY b.rdate
as demonstrated here: http://sqlfiddle.com/#!9/f6871/2

MySQL Join 2 columns from table y into rows of table x

Trying to wrap my mind around how to write this SQL query.
Table X has 3 Columns: Year, ID, Value and looks like so
Year | ID | Value
2013 101 10000
2014 101 11000
2015 101 12000
2013 102 7000
2014 102 8000
2015 102 9000
And table Y has 3 Columns: ID, Curr_Year_Val, Next_Year_Val and looks like this
ID | Curr_Year_Val | Next_Year_Val
101 13000 14000
102 6000 5000
I would like to write a select statement to join these two tables together, but maintain the layout of Table X, like so:
Year | ID | Value
2013 101 10000
2014 101 11000
2015 101 12000
Curr_Year_Val 101 13000
Next_Year_Val 101 14000
Is there a way to achieve this result? I've figured out how to just do a left join to add the columns from table y to table x, but would rather have the columns from table y unpivoted to the rows of table x. Thanks much in advance - this seems like it should be so easy, I've been googling for hours but I'm probably not using the proper terminology for what I'm trying to do in my searches.
Thanks!
Sounds like you should use union all:
select year, id, value from x
union all
select 'curr_year_val', id, curr_year_val from y
union all
select 'next_year_val', id, next_year_val from y
order by 2, 1
SQL Fiddle Demo
BTW, other databases would require you to have the same data types for all columns when using union. This works though with mysql.
Uee union
select year, id, value
from tableX
where id ='101'
union
select 'curr_year_val', id, curr_year_val
from tableY
where id ='101'
union
select 'next_year_val', id, next_year_val
from tableY
where id ='101'

While joining 2 mysql tables how to get only the required related row in second table

I have the following 2 tables A and B in MySQL db. When I join the 2 tables by the VisitID (A.VisitID = B.VisitID) I want to pickup only the records that related the latest Actiondateandtime from the table B for a VisitID. For example for VisitID = 85 I want to pickup the row with 15/10/2014 3:44 in table B. For VisitID = 86 I only want to pickup the row with 09/10/2014 1:28 in table B.
Table A :
VisitID VisitTitle VisitSummary Conclusion
85 Go to Paddy Field 1 Checked Temperatures 1
86 Soil Quality Checked Checked PHP of different soil 2
87 Go to Paddy Field 2 Collected Soil samples 0
Table B:
RefID VisitID ActionDesc Actiondateandtime
1 85 Submiited to Management 9/10/2014 12:03
2 86 Sent to lab 9/10/2014 1:06
3 86 Sent to lab 9/10/2014 1:07
4 86 Sent to lab 9/10/2014 1:21
5 86 Sent to lab 9/10/2014 1:28
6 87 Followed with Soil scientist 9/10/2014 1:32
7 87 Followed with Soil scientist 9/10/2014 1:33
8 85 Submitted to Management 15/10/2014 3:44
I want the result after the join of these 2 tables
A.VisitID A.VisitTitle A.Conclusion B.RefID B.VisitID B.Actiondateandtime
85 Go to Paddy Field 1 1 8 85 15/10/2014 3:44
86 Soil Quality Checked 2 5 86 9/10/2014 1:28
87 Go to Paddy Field 2 0 7 87 9/10/2014 1:33
What MySQL code needed to get this required result?
One option is to join the table back to itself using the max aggregate to get the max date grouped by visitid:
select a.visitid, a.visittitle, a.conclusion, b.refid, b.actiondateandtime
from tablea a
join tableb b on a.visitid = b.visitid
join (
select visitid, max(actiondateandtime) actiondateandtime
from tableb
group by visitid
) c on b.visitid = c.visitid and b.actiondateandtime = c.actiondateandtime
SQL Fiddle Demo
try this.....
select *
from Table At1
inner join TableB t2 on t1.VisitID =t2.VisitID
where t2.Actiondateandtime in (select max(Actiondateandtime )
from TableB
group by VisitID)
check this fiddle http://sqlfiddle.com/#!2/e4f80/2

getting all records from a table that match a result set

this is going to sound a bit bizarre ...but let me try to explain
id phone
1 123
2 234
3 456
4 4564
5 9876
..............
1000 123
2000 234
3000 456
5000 123
i need to a write a query in such a manner that when i pull the first 5 records of the table the query will also search in the same table for the phone numbers that are occurring in the first 5 records
so the final result set will be
id phone
1 123
2 234
3 456
4 4564
5 9876
1000 123
2000 234
3000 456
5000 123
i know i can separate the same query first pull the first 5 and then iterate through each of the phone numbers to pull records if they match the phone number. but was looking to do a single statement ...if its possible ...
thanks
Something like
SELECT ...
FROM yourtable
WHERE phone IN (
SELECT DISTINCT phone
FROM yourtable
ORDER BY ...
LIMIT 5
)
?
Select t1.id,t2.phone from yourtable as t1
left join yourtable as t2 on t2.phone = t1.phone