Sum latest records from each user - mysql

I have a table as below
id user_id bal createdDate
1 001 100 2015-02-17 16:45:44
2 001 200 2015-02-18 18:45:44
3 002 300 2015-02-20 16:45:44
4 002 800 2015-02-18 18:45:44
5 001 300 2015-03-01 16:20:44
6 002 500 2015-03-17 16:45:44
7 002 200 2015-03-18 18:45:44
8 003 300 2015-03-10 16:45:44
9 003 80 2015-03-18 18:45:44
10 003 200 2015-03-21 16:20:44
I want the latest balance of each user_id and sum all of them. As a result, i will get sum of combine latest balance from user 001,002,003
This table contain around 5 million records
This table save the history of account balance for each user. So the latest date is the latest account balance for that user.
Below is my query, but I don't get any result as my MySQL workbench froze.
SELECT (SUM(bal))
FROM hist_bal h1
WHERE h1.createDate = (SELECT MAX(h2.createDate)
FROM hist_bal h2
WHERE h2.user_id = h1.user_id GROUP BY h2.user_id)

This should do it simply, no need for GROUP BY clouse:
SELECT SUM(bal)
FROM hist_bal h1
WHERE h1.createDate = (SELECT MAX(h2.createDate)
FROM hist_bal h2
WHERE h2.user_id = h1.user_id)

SELECT SUM(h1.bal) AS Bal
FROM hist_bal h1 JOIN (SELECT user_id, MAX(h2.createDate) AS createDate
FROM hist_bal h2 GROUP BY h2.user_id) h2 ON h1.user_id = h2.user_id
AND h1.createDate = h2.createDate

Related

Need to derive count of occurrence in Table 2 based on the results of Occurrence in Table 1 using sql query

Table_1 has order_id, country_id details
table_ID order_id country_id
1 100 IN
2 200 USA
3 300 UK
4 400 IN
5 500 UK
6 600 UK
7 700 USA
8 800 USA
9 900 IN
10 1000 UK
Table_2 has shipment_id, order_id details
Shipment_ID order_id
1 100
2 100
3 100
4 200
5 200
6 300
7 300
8 400
9 500
11 500
12 600
13 700
14 700
15 700
16 700
17 800
18 800
19 800
20 900
21 900
22 1000
23 1000
24 1000
I used the following query to find out list of order_id which are for country_id='IN'
select `order_id`
from `Table_1`
where `country_id` = 'IN';
order_id
100
400
900
I need guidance to write the query to find the count of shipment_id which will are mapped to order_id from 'IN'
So order_id 100 has 3 shipment, 400 has 1 and 900 has 2 shipment
Desired final output
count_of_shipment_id
6
here is the query you need:
SELECT country_id, count(*) as count_of_shipment_id
FROM Table_1 a
inner join Table_2 b on a.`order_id` = b.`order_id`
group by country_id
if you need only one country you can always add "where" or "having" to filter the result.
here you can see the sample you posted:
http://sqlfiddle.com/#!9/c90424/2

MySQL Getting a daily average of last 2 records grouped by user

i have a MySQL table like the following:
PKey ReadID UserID Date Used
1 abc 101 2015-02-01 553
2 abc 102 2015-02-01 1090
3 abc 103 2015-05-01 640
4 def 104 2015-06-01 140
5 ghi 101 2015-07-01 780
6 ghi 102 2015-07-01 2108
7 ghi 103 2015-07-01 778
8 jkl 104 2015-12-07 198
9 jkl 105 2015-12-07 101
10 jkl 102 2015-12-07 2500
11 jkl 103 2015-12-07 898
So what im trying to end up with a daily average Used for a particular ReadID, grouped by the UserID.
For example, to end up with the below output for ReadID = jkl
UserID Daily Avg
102 2.465
103 0.754
104 0.306
105 n/a
If i use the above table, the calculation for UserID = 102 with ReadID = jkl is:
select (2500 - 2108 ) / DateDiff ('2015-12-07', '2015-07-01')
This gives an answer of 2.465
These figures come from:
select (current Used - last previous Used ) / DateDiff('current Date', 'last previous Date')
So I can do it for one UserID at a time , but not for all the UserID in a particular ReadID.
Can anyone tell me how to do this?
There are functions that allow you to take the average of given values, and there are clauses that allow you to Group aggregated information (like averages) according to other values. Given that, try something like this:
SELECT AVG(Used) FROM [table] WHERE date = [date] GROUP BY UserID
Also, I recommend you take a look at the MySQL 5.7 Reference Guide. This link has information on GROUP BY functions, and you can find information on averages if you look a little bit.
I have tried the below for a few ReadID and it seems to be working :
SELECT x.MeterID,(x.Used - y.lastused) / DATEDIFF( x.date, y.lastdate) AS dailyavg
FROM
(SELECT PKey,ReadID,UserID, Date AS date,Used
FROM table1
WHERE ReadID = 'jkl') x
JOIN
(SELECT MAX(PKey) lastpkey,ReadID,MeterID,MAX(Date) AS lastdate,Max(Used) AS lastused
FROM table1
WHERE Date < (select MIN(Date) FROM table1 WHERE ReadID = 'jkl')
GROUP BY MeterID
Order BY Date DESC ) y
ON y.MeterID = x.MeterID

MySQL: Finding the missing values from tables

I have two different tables:
checkin_out consists of two fields: emp_code, checked_date
temp_days consists of two fields: id, date_value
Table checkin_out has following data:
emp_code | checked_date
-----------------------
001 2012-11-01
001 2012-11-02
001 2012-11-03
002 2012-11-01
003 2012-11-01
003 2012-11-02
While table temp_days has following data:
id | date_value
-----------------
1 2012-11-01
2 2012-11-02
3 2012-11-03
4 2012-11-04
5 2012-11-05
From the above tables, I need to show the missing dates in the table temp_days; I need to query to get a result as follow:
emp_code | date_value
-----------------------
001 2012-11-04
001 2012-11-05
002 2012-11-02
002 2012-11-03
002 2012-11-04
002 2012-11-05
003 2012-11-03
003 2012-11-04
003 2012-11-05
If anyone could help, please! Thanks!
The below works for a more complex data set with multiple emp_codes.
SELECT alldays.emp_code, alldays.date_value
FROM (
SELECT date_value, emp_code
FROM temp_days
CROSS JOIN checkin_out
GROUP BY date_value, emp_code
) alldays
LEFT JOIN checkin_out C
ON alldays.date_value = C.checked_date
AND alldays.emp_code = C.emp_code
WHERE C.emp_code IS NULL
SELECT c.emp_code, a.date_value
FROM temp_days a
LEFT JOIN checkin_out b
ON a.date_value = b.checked_date
CROSS JOIN
(
SELECT emp_code
FROM checkin_out
GROUP BY emp_code
) c
WHERE b.emp_code IS NULL
SQLFiddle Demo

Datediff in date format

I have 2 tables with structure as
Emp Table
id name
001 Smith
002 Jerry
Leave
sr.no reason from_date to_date request_by status
1 PL 2011-12-11 2011-12-15 001 Declined
2 PL 2011-11-13 2011-11-13 001 Approved
3 PL 2011-10-02 2011-10-05 002 Declined
Now I have written this query
select DATEDIFF(Leave.from_date,Leave.to_date)as cdate,
Emp.id as emp
from Leave left join Emp
on Leave.request_by=Emp.id
gives me difference between these 2 dates like...
cdate emp
-4 001
0 001
-3 002
The first thing about this output difference between '2011-12-11 & 2011-12-15 ' need to be 5 as for 5 consecutive days employee is absent. That we achieve it.
But I need this cdate in date format like('%Y%m%d') and + if date difference is say -4 then 4 records should be displayed for that.
So I want to write a query which gives output like this......
cdate emp
2011-12-11 001
2011-12-12 001
2011-12-13 001
2011-12-14 001
2011-12-15 001
2011-11-13 001
2011-10-02 002
2011-10-03 002
2011-10-04 002
2011-10-05 002
So can anybody tell me what how should I need to write my query to get this output?
Try this query -
CREATE TABLE temp_days(d INT(11));
INSERT INTO temp_days VALUES
(0),(1),(2),(3),(4),(5),
(6),(7),(8),(9),(10),
(11),(12),(13),(14),(15); -- maximum day difference, add more days here
SELECT l.from_date + INTERVAL td.d DAY cdate, e.id emp
FROM
`leave` l
LEFT JOIN Emp e
ON l.request_by = e.id
JOIN temp_days td
ON DATEDIFF(l.to_date, l.from_date) >= td.d
ORDER BY
e.id

I need help writing a summation query in MySQL

I have a table that looks like this:
posid sales eid
1 20 001
1 20 002
1 30 001
2 30 001
1 30 002
2 30 001
1 30 002
2 20 002
2 10 002
I want to write a query that would give me sum of sales for each employee on particular pos. the result needs to be like this.
pos id emp id sales
1 001 50
1 002 80
2 001 60
2 002 30
How would I do this?
Use group by:
select t.posid
, t.eid
, sum(t.sales) as sales_by_posid
from mytable t
group by t.posid, t.eid
order by sales_by_posid desc
SELECT
posID, empID, sum(sales)
FROM your_table
GROUP BY posID, empID
ORDER BY posID, empID
Here's a group by tutorial: http://www.tizag.com/mysqlTutorial/mysqlgroupby.php