MySQL last value of day - mysql

I am trying to construct a query that produces one value per day and I want that value to be the last recorded value of the day. This is what my table looks like (actual dataset contains a row for each minute):
+------------+----------+-------+
| Date | Time | Value |
+------------+----------+-------+
| 2015-06-14 | 13:00:00 | 3 |
| 2015-06-14 | 14:00:00 | 5 |
| 2015-06-15 | 11:00:00 | 6 |
| 2015-06-15 | 17:00:00 | 9 |
| 2015-06-16 | 09:00:00 | 2 |
| 2015-06-16 | 10:00:00 | 4 |
+------------+----------+-------+
I would like the outcome of the query to look like this:
+------------+----------+-------+
| Date | Time | Value |
+------------+----------+-------+
| 2015-06-14 | 14:00:00 | 5 |
| 2015-06-15 | 17:00:00 | 9 |
| 2015-06-16 | 10:00:00 | 4 |
+------------+----------+-------+
What would the SQL-statement need to be to retrieve this result? Any help is much appreciated!

select t1.date,
t1.time,
t1.value
from table t1
where t1.time= (select max(t2.time)
from table t2
where t2.date = t1.date);

Related

Trailing n-day cumulative sum in mysql

I have this structure:
+--------------------------------------+---------------------+--------+-------------+-------------+
| id | start | User | billedHours | trail90dsum |
+--------------------------------------+---------------------+--------+-------------+-------------+
| 2e88f9f9-2543-11eb-9d57-02b150913215 | 2018-10-04 11:00:00 | User 1 | 15.30 | NULL |
| 2e89af0a-2543-11eb-9d57-02b150913215 | 2018-10-09 12:00:00 | User 1 | 0.40 | NULL |
| 2e8a400b-2543-11eb-9d57-02b150913215 | 2018-10-09 17:00:00 | User 2 | 0.60 | NULL |
| 2e8ae87d-2543-11eb-9d57-02b150913215 | 2018-10-25 17:30:00 | User 2 | 0.30 | NULL |
| 2e8ba472-2543-11eb-9d57-02b150913215 | 2018-10-27 15:00:00 | User 3 | 1.20 | NULL |
| 2e975c93-2543-11eb-9d57-02b150913215 | 2018-10-29 17:30:00 | User 3 | 0.30 | NULL |
| 2e980477-2543-11eb-9d57-02b150913215 | 2018-11-02 13:30:00 | User 1 | 1.90 | NULL |
| 2e98a874-2543-11eb-9d57-02b150913215 | 2018-11-03 12:00:00 | User 2 | 0.70 | NULL |
| 2e993a7d-2543-11eb-9d57-02b150913215 | 2018-11-04 13:30:00 | User 3 | 1.30 | NULL |
| 2ea9fa03-2543-11eb-9d57-02b150913215 | 2018-11-11 11:00:00 | User 1 | 0.90 | NULL |
+--------------------------------------+---------------------+--------+-------------+-------------+
I am looking for an UPDATE query that will fill the trail90dsum field with SUM(billedHours) for each user within the trailing 90 days (as of each start date).
I was able to construct a SELECT query with a join for reporting the data, but I can't transform it to work in the UPDATE syntax.
Thanks,
Phillip
Thanks for all the help. This query got the job done:
UPDATE mytable dst JOIN
(SELECT t1.user, t1.start, t1.billedHours, SUM(t2.billedHours) as last90
FROM mytable as t1 JOIN mytable as t2 ON DATEDIFF(t1.start, t2.start) BETWEEN 0
AND 90 WHERE t1.user=t2.user
GROUP BY t1.user, t1.start, t1.billedHours) src
SET dst.trail90dsum=src.last90
WHERE src.start=dst.start and src.user=dst.user
Thanks, -P

Filtering out duplicate data based on more than one value in MySQL 8

I have a simple table like so
+----+---------------------+
| id | datetime |
+----+---------------------+
| 1 | 2019-05-05 16:00:00 |
| 1 | 2019-05-05 17:00:00 |
| 1 | 2019-05-05 18:00:00 |
| 1 | 2019-05-05 18:00:00 |
| 2 | 2019-05-05 16:00:00 |
| 2 | 2019-05-05 17:00:00 |
| 2 | 2019-05-05 18:00:00 |
| 3 | 2019-05-05 17:00:00 |
| 3 | 2019-05-05 17:00:00 |
+----+---------------------+
I'd like to filter out all the rows with duplicate datetime entries for each id, so that I may end up with a table like this:
+----+---------------------+
| id | datetime |
+----+---------------------+
| 1 | 2019-05-05 16:00:00 |
| 1 | 2019-05-05 17:00:00 |
| 1 | 2019-05-05 18:00:00 |
| 2 | 2019-05-05 16:00:00 |
| 2 | 2019-05-05 17:00:00 |
| 2 | 2019-05-05 18:00:00 |
| 3 | 2019-05-05 17:00:00 |
+----+---------------------+
What is the easiest way to do this in MySQL?
EDIT: Let's say I had another column called weight that assigns a numerical weight to each row of data. Is there a way to tell MySQL to filter out the duplicate datetime entries for each id based on which one has the largest weight?
use distinct
select distinct id,datetime from table_name
after your edit it seems you need row_number()
select * from
(select *,
row_number() over(partition by id,datetime order by weight desc) rn
from table_name
) a where a.rn=1
You seem to want:
select t.*
from t
where t.weight = (select max(t2.weight)
from t t2
where t2.id = t.id and t2.datetime = t.datetime
);

How to determine that the date is included in a particular month and to join the tables?

I have the first table which stores hourly information about the status of the object.
| TIME_KEY | ID_OBJECT | STATUS |
|---------------------|-----------|--------|
| 2018-01-01 00:00:00 | 1 | IN |
| 2018-01-01 00:00:00 | 2 | OUT |
| 2018-01-01 01:00:00 | 1 | OUT |
| 2018-01-01 01:00:00 | 2 | IN |
| 2018-02-01 00:00:00 | 1 | IN |
| 2018-02-01 00:00:00 | 2 | OUT |
| 2018-02-01 01:00:00 | 1 | OUT |
| 2018-02-01 01:00:00 | 2 | IN |
The second table stores the code name of the object in a certain month.
| MONTH_KEY | SITE_ID | NAME |
|---------------------|-----------|------------|
| 2018-01-01 | 1 | Apple |
| 2018-01-01 | 2 | HP |
| 2018-02-01 | 1 | Samsung |
| 2018-02-01 | 2 | Blackberry |
How correctly join this two table and return such result?
| TIME_KEY | ID_OBJECT | STATUS | NAME |
|---------------------|-----------|--------|------------|
| 2018-01-01 00:00:00 | 1 | IN | Apple |
| 2018-01-01 00:00:00 | 2 | OUT | HP |
| 2018-01-01 01:00:00 | 1 | OUT | Apple |
| 2018-01-01 01:00:00 | 2 | IN | HP |
| 2018-02-01 00:00:00 | 1 | IN | Samsung |
| 2018-02-01 00:00:00 | 2 | OUT | Blackberry |
| 2018-02-01 01:00:00 | 1 | OUT | Samsung |
| 2018-02-01 01:00:00 | 2 | IN | Blackberry |
you can convert date to month and can join
select t2.TIME_KEY,t1.ID_OBJECT,STATUS,NAME
FROM table1 t1 JOIN
table2 t2 on month(t1.TIME_KEY)=month(t2.TIME_KEY) and t1.ID_OBJECT=t2.SITE_ID
You can use a correlated subquery:
select t1.*,
(select t2.name
from table2 t2
where t2.site_id = t1.object_id and
t1.time_key >= t2.month_key
order by t2.month_key desc
limit 1
) as name
from table1 t1;
This will take the most recent name, even if it is not in the current month. I am guessing that is desirable behavior.
You need JOIN & conversations :
SELECT T1.TIME_KEY, T1.ID_OBJECT, T1.STATUS, T2.NAME
FROM table1 T1 INNER JOIN
table2 T2
ON T1.ID_OBJECT = T2.SITE_ID AND
CAST(T2.MONTH_KEY AS DATE) = CAST(T1.TIME_KEY AS DATE);

Compare output of select statement

My Table1
| Participantsid | Validfrom | Validto |
| 2,4,1 | 2016-02-21 10:22:00 | 2016-02-21 12:22:00 |
| 2,4,1 | 2016-03-04 10:00:00 | 2016-03-04 10:25:00 |
| 2,3,4,1 | 2016-02-19 10:43:00 | 2016-02-19 11:08:00 |
| 2,3,4,1 | 2016-02-22 11:32:00 | 2016-02-22 11:57:00 |
| 4,6,5 | 2016-02-20 17:00:00 | 2016-02-20 18:00:00 |
| 1,2,5 | 2016-02-22 18:00:00 | 2016-02-22 19:00:00 |
| 2,3,6,1 | 2016-03-23 10:00:00 | 2016-03-23 11:00:00 |
| 1,2,3,5 | 2016-02-20 12:00:00 | 2016-02-20 14:00:00 |
| 2,6 | 2016-02-20 12:00:00 | 2016-02-20 13:00:00 |
Another Table2
+--------------+------------+
| EmployeeName | EmployeeID |
+--------------+------------+
| Mathews | 1 |
| Gerald | 2 |
| Bravo | 3 |
| Smith | 4 |
| George | 5 |
| Bailey | 6 |
| Stephen | 9 |
| Balu c | 10 |
I have some inputid's=1,5,6.
Now I have to compare this input id's with Participantsid from table1 for a given validfrom and validto date and if there is a match I need to get the name corresponding to that id.
Emaple:- inputid's=1,2,3 for from- 2016-02-22 18:00:00, to-2016-02-22 19:00:00
it should give me o/p =mathews,gerald
I am currently writing two select statements and using one for loop which gives me the result but its wrong
I am trying to do it in a single query but no way near to my required output.please help
Desired result can be achieved by using group_concat and find_in_set with sub-query.
SQLFiddle:
http://sqlfiddle.com/#!9/ce893/1
select group_concat(EmployeeName) as `o/p`
from Table2
where FIND_IN_SET(EmployeeID,
(select Participantsid from Table1
where Validfrom = '2016-02-22 18:00:00' and Validto = '2016-02-22 19:00:00'));

MySQL - Modify datetime columns based on additional datetime columns

I had a rough time figuring out how to title this, but here's an explanation...
I have two tables
Table #1:
--------------------------------------------------------------
| id | start | end | duration |
-------------------------------------------------------------
| 1 | 2013-10-01 09:00:00 | 2013-10-01 09:30:00 | 30 |
-------------------------------------------------------------
| 2 | 2013-10-02 10:00:00 | 2013-10-02 10:30:00 | 30 |
--------------------------------------------------------------
| int | datetime | datetime | int |
--------------------------------------------------------------
Table #2:
---------------------------------------------------
| id | start | end |
---------------------------------------------------
| 3 | 2013-10-01 09:00:00 | 2013-10-01 17:00:00 |
---------------------------------------------------
| 4 | 2013-10-02 09:00:00 | 2013-10-02 17:00:00 |
---------------------------------------------------
| int | datetime | datetime |
---------------------------------------------------
What I'm trying to do is grab the all records from table #2 match any table #1 rows that fall on the same date and within the same datetime and modify the result set by removing the times from table #1...
An example result would be...
---------------------------------------------------------
| table2id | start | end |
---------------------------------------------------------
| 3 | 2013-10-01 09:30:00 | 2013-10-01 17:00:00 |
---------------------------------------------------------
| 4 | 2013-10-02 09:00:00 | 2013-10-02 10:00:00 |
---------------------------------------------------------
| 4 | 2013-10-02 10:30:00 | 2013-10-02 17:00:00 |
---------------------------------------------------------
How can this be achieved?
Though I can't be sure this logic would be correct, something like this might be close to what you're looking for:
UPDATE tbl2
SET start = (SELECT end FROM tbl1 WHERE start = tbl2.start)
It's not terribly clear how these two tables relate. However, id clearly doesn't. The only two values that match in your example are the start values.
SELECT Table2.id, Table1.end_date , Table2.end_date
FROM table1 AS Table1, table2 AS Table2
WHERE
Table1.start_date >= Table2.start_date
AND Table1.end_date <= Table2.end_date
UNION
SELECT Table2.id, Table2.start_date , Table1.start_date
FROM table1 AS Table1, table2 AS Table2
WHERE
Table1.start_date >= Table2.start_date
AND Table1.end_date <= Table2.end_date
this works but will give you an extra record with identical start and end that you have to manually delete
---------------------------------------------------------
| table2id | start | end |
---------------------------------------------------------
| 3 | 2013-10-01 09:30:00 | 2013-10-01 17:00:00 |
| 4 | 2013-10-02 10:30:00 | 2013-10-02 17:00:00 |
| 3 | 2013-10-01 09:00:00 | 2013-10-01 09:00:00 | --> Extra Record
| 4 | 2013-10-02 09:00:00 | 2013-10-02 10:00:00 |