get highest date between two date column in mysql query - mysql

Hello I have two column of date time of multiple rows i want to fetch row with latest date(highest) between two column of all record. Please check below:
ID|Date1 |Date2
1 |2021-06-10 19:03:36 |Null
2 |2021-06-11 19:33:41 |2021-06-16 09:49:41
3 |2021-06-16 20:04:24 |Null
I want to get highest date from all record of two column(Date1 and Date2). From above table, I want third row date because this is highest date(2021-06-16 20:04:24) from all record of two column. If we change the date1 column row 3 by 2021-06-16 09:20:41 then result will be row 2 because highest date record found in date2. Please help me for creating mysql query for getting full data row

If you want only 1 row in the results and you don't care about ties, then use GREATEST() to get the max date in each row, sort by that max date descending and use LIMIT 1 to pick the top row:
SELECT *
FROM tablename
ORDER BY GREATEST(COALESCE(Date1, '1000-01-01'), COALESCE(Date2, '1000-01-01')) DESC
LIMIT 1
If Date1 is not nullable use COALESCE() only for Date2:
SELECT *
FROM tablename
ORDER BY GREATEST(Date1, COALESCE(Date2, '1000-01-01')) DESC
LIMIT 1
See the demo.

You can union the two columns and get the MAX():
SELECT MAX(dateColumns)
FROM
(
SELECT DATE1 as dateColumns FROM yourtable
UNION ALL
SELECT DATE2 FROM yourtable
) sub

One way to do this with somewhat minimal SQL where "yourtable" is whatever the name of your table is:
select ID, Date1, Date2
from yourtable
where greatest(
coalesce(Date1,'1900-01-01'),
coalesce(Date2,'1900-01-01')
) in (
select max(greatest(
coalesce(Date1,'1900-01-01'),
coalesce(Date2,'1900-01-01')
)) from yourtable
)
However, performance of this kind of query may not scale for huge tables. EDIT: Updated to include coalesce() of null dates to an arbitrarily "early" date.

Related

Mysql. how to join two tables from this example?

everybody.
I have two requests.
1 query - show the list of dates with time 22:00 from one table
SELECT DATE_FORMAT(tt.create_time,"%Y-%m-%d 22:00:00") AS DAY,tt.id
FROM tick tt
GROUP BY DATE_FORMAT(tt.create_time,"%Y-%m-%d")
2 query - shows the number of records that have create_time less than the date specified in the query
SELECT COUNT(*) AS count FROM
(SELECT * FROM
(SELECT * FROM tick_history th
WHERE th.create_time < '2019-04-15 22:00:00'
ORDER BY th.id DESC) AS t1
GROUP BY t1.tick_id) AS t2
WHERE t2.state NOT IN (1,4,9) AND t2.queue = 1
Is it possible to somehow combine these two queries to get one column with dates from the first query, and the second column is the number from the second query for each date from the first column?
Ie as if substituted date and calculated the number of the second request..
Is it possible? Help with request please

How can i include previous row in a selected range if condition is not satisfied

I am trying to find out a maximum number from a given date ranges.
for example, my table contains
date number
---------- --------
01-01-2019 1
05-01-2019 3
07-01-2019 2
10-01-2019 1
11-01-2019 2
and I want to find the max number in date from 06-01-2019 to 11-01-2019
When I use the query,
select max(count) from TABLE where date between startDate and endDate;
the output is 2.
But what I wanted is if the startDate is not in the table, to include the previous row. For example in the previous case, I want to include the row 05-01-2019 and thus the output should be 3.
Is there any query for this process or do I need to write an algorithm?
Assume the dates in table are sorted and I use a MySQL database.
You can do this by using subquery
SELECT MAX(number)
FROM TABLE
WHERE date >= (
SELECT date
FROM TABLE
WHERE date <= startDate
ORDER BY date DESC
LIMIT 1
)
AND date <= endDate
Subquery will return largest nearest date to startDate.
This date can then be used as a minimum value for your outer query.
In MySQL 8+, you can use lead():
select max(number)
from (select t.*, lead(date) over (order by date) as next_date
from t
) t
where next_date > $start_date and
date <= $end_date;

mysql - group by to get oldest and newest dates into one row

I have tbl_events
key userID date
1 1 1.1.2000
2 1 1.1.2017
3 2 2.2.1990
I'm trying to get this:
select distinct userID, date [that is earliest eg row 1] as earliest_date,
date [that is latest eg row 2] as latest_date
from tbl_events
if a userid has only one row in tbl_events then tbl_events.date would serve as both the earliest and latest_date
ie my result would be:
userID earliest_date latest_date
1 1.1.2000 1.1.2017
2 2.2.1990 2.2.1990
I can do this rather inefficiently with lots of looping but I'm wondering if there is a way to do this with "group by" or i have seen queries that seem to contain additional select statements in brackets
If anyone can please point me in the right direction I'd be very grateful.
Thank you.
Nick
You can use MAX() and MIN() aggregate function probably saying
select userid, max(`date`) as earliest_date,
min(`date`) as furthest_date
from tbl
group by userid;

Find average between two date columns for specific rows in a group

I have a table with 2 dates in it and a product, and I need to get the average days difference between them considering just the last 3 rows for each product.
SELECT AVG(DATEDIFF(date2, date1)) FROM table WHERE product = 121
This gives me the average of all the date differences for product 121
SELECT AVG(DATEDIFF(date2, date1)) FROM table WHERE product = 121 LIMIT 3
Still gives me the average off all the records, ignoring the LIMIT argument.
Also when I try a different approach, it also does ignore the last argument and shows the average off all the rows.
SELECT AVG(DATEDIFF(date2, date1)) FROM table WHERE product =121 && date1 > 2015-01-01
Any idea on how to fix this or what I'm doing wrong?
When you have problems like this, I recommend breaking it up and putting it back.
Before doing any calculations, you know that you need the last three rows for each product. So, if you want for example the rows with the latest date2 you can select them by doing the following:
SELECT *
FROM myTable
WHERE product = 121
ORDER BY date2 DESC
LIMIT 3;
That will select the 3 latest rows you want. Then, just use that as a subquery to preform the aggregation. This way, the calculations are only made on the rows you are concerned with:
SELECT product, AVG(DATEDIFF(date2, date1))
FROM(
SELECT product, date1, date2
FROM myTable
WHERE product = 121
ORDER BY date2 DESC
LIMIT 3) tempTable;

How do I use group by showing the newest row of data

Can someone please tell me how to use the group by clause, grouping by one of the keys in the table but yet having the newest timestamp at the top? I have multiple rows of data but I only want to show the newest row
If you want only the most recent one per group:
SELECT somefield
FROM table t1
WHERE timestamp = (SELECT MAX(timestamp)
FROM table t2
WHERE t1.somefield = t2.somefield);
Or just the latest most recent one:
SELECT somefield
FROM table
GROUP BY somefield
ORDER BY MAX(timestamp) DESC
LIMIT 1;
I think you're looking for the ORDER BY clause.
SELECT Foo.Bar, Foo.SomeTimestamp
FROM Foo
ORDER BY Foo.SomeTimestamp DESC
If you're grouping by a column, you're probably returning aggregate data. If the timestamp is unique for each row of aggregate data, you may need to use the MAX function (or the like) to return a single timestamp for each group. For example:
SELECT Foo.TypeID, SUM(Foo.Price) AS Price, MAX(Foo.OrderDate) AS LastOrder
FROM Foo
GROUP BY Foo.TypeID
ORDER BY MAX(Foo.OrderDate) DESC
If you only want the first row, you can use the LIMIT clause:
SELECT Foo.Bar, Foo.SomeTimestamp
FROM Foo
ORDER BY Foo.SomeTimestamp DESC
LIMIT 0, 1
This starts at row 0 and returns at most 1 row.