get the timestamp for the minimum/maximum value - mysql

i am new in learning sql. how to create query to get the timestamp of a minimum value and the minimum value itself?
previously i managed to get the minimum value but not with its timestamp. with this query
SELECT min(score) as lowest
FROM rank
WHERE time >= CAST(CURDATE() AS DATE)
here is the table that i've created:
(cannot attach image because of the reputation rule)
sorry for the bad english.

If you either expect that there would be only a single record with the lowest score, or if there be ties, you don't care which record gets returned, then using LIMIT might be the easiest way to go here:
SELECT timestamp, score
FROM rank
WHERE time >= CAST(CURDATE() AS DATE)
ORDER BY score
LIMIT 1;
If you care about ties, and want to see all of them, then we can use a subquery:
SELECT timestamp, score
FROM rank
WHERE time >= CAST(CURDATE() AS DATE) AND
score = (SELECT MIN(score) FROM rank WHERE time >= CAST(CURDATE() AS DATE));

It's possible by following way.
Note: It only works if you want to get a single record at once
select score, time
FROM rank
WHERE time >= CAST(CURDATE() AS DATE)
ORDER BY score ASC LIMIT 1

Related

Select dates from the future or past, if future is not available

I have a simple table for events with a date column. I can easily select
the next n events with (assuming n = 3):
SELECT * FROM events WHERE `date` > NOW() ORDER BY `date` LIMIT 3
However, not aways there will be 3 events in the future. In this case,
I'd like to return the ones available in the future and complete what is
missing with the closest ones to today. E.g., if today is day 12-04, the
following dates marked with a * should be selected of the whole list:
10-03
20-03
30-03 *
10-04 *
20-04 *
While I can easily check the result of the first query to find out how
many rows were returned and build another query to find the past dates
if necessary, I'm interested to know if there is a way to fetch these
rows in a single query.
You can use multiple keys in the order by. So:
SELECT e.*
FROM events
ORDER BY (date > now()) DESC, -- future events first
(CASE WHEN date > now() THEN date END) ASC -- nearest future events first
date DESC -- other dates in descending order
LIMIT 3;
If your table is large, it is probably faster to get three events from the near future and near past and combine those:
select e.*
from ((select e.*
from events e
where date > now()
order by date asc
limit 3
) union all
(select e.*
from events e
where date <= now()
order by date desc
limit 3
)
) e
order by date desc
limit 3;

Result by server Date

how to add query result as current date and less days. do not want fixed days pl help in mysql
select
Winner,
Coupon,
DATE_FORMAT(date, '%d-%m-%Y') AS `Date`
FROM table2
ORDER BY DATE_FORMAT(date, '%d-%m-%Y')
LIMIT 1, 30
You can add a where clause to that statement and use <= now() to get the rows less than or equal to the current datetime.
select
Winner,
Coupon,
DATE_FORMAT(date, '%d-%m-%Y') AS `Date`
FROM table2
where datecolumn<=now()
ORDER BY DATE_FORMAT(date, '%d-%m-%Y')
You can use limit 1 to return just one row. http://dev.mysql.com/doc/refman/5.7/en/select.html
Your current limit statement, LIMIT 1, 30, is returning the second row though the thirty first row (the first value is the offset, the second is the number of rows).

MYSQL order by datetime

I need to select one row with the "highest" date and time from a table, but I can't get the highest one, the ORDER BY DESC doesn't work.
Here's my query:
SELECT count(*) as c,
start,
UNIX_TIMESTAMP(start) as S,
duration
FROM appuntamento
WHERE DATE(start) = DATE('2014-04-08 18:30:00')
ORDER BY S DESC
LIMIT 1
I don't care about getting the start value in unix timestamp, it was the nth try to get through this
Any tips?
A few problems here. First, the presence of COUNT(*) turns this into an aggregate query, which do you not want. That's probably the cause of your trouble.
Second, if you have a lot of rows in your appuntamento table the performance of this query will be bad, because you can't use an index.
Presuming that you want the time and duration of the last (latest-in-time) row from a particular day in your table, and the number of appointments for that same day, you need to do this:
SELECT a.start, a.duration, b.count
FROM (
SELECT start,
duration
FROM appuntamento
WHERE start >= DATE('2014-04-08 18:30:00')
AND start < DATE('2014-04-08 18:30:00') + INTERVAL 1 DAY
ORDER BY start DESC, duration DESC
LIMIT 1
) AS a
JOIN (
SELECT COUNT(*) AS count
FROM appuntamento
WHERE start >= DATE('2014-04-08 18:30:00')
AND start < DATE('2014-04-08 18:30:00') + INTERVAL 1 DAY
) AS b
Explanation: First, this form of searching on start allows you to use an index on the start column. You want that for performance reasons.
WHERE start >= DATE('2014-04-08 18:30:00')
AND start < DATE('2014-04-08 18:30:00') + INTERVAL 1 DAY
Second, you need to handle the COUNT(*) as a separate subquery. I have done that.
Third, you can definitely do ORDER BY start DESC and it will work if start is a DATETIME column. No need for UNIX_TIMESTAMP().
Fourth, I used ORDER BY start DESC, duration DESC to arrange to return the longest appointment if there happen to be several with the same start time.
if all you want is one row returned then use the MAX() function without the order. should do the trick.
SELECT count(*) as c,
MAX(start) as highest_date,
UNIX_TIMESTAMP(start) as S,
duration
FROM appuntamento
WHERE DATE(start) = DATE('2014-04-08 18:30:00')
also with your order by statement. you need to add a group by so that you aren't combining incorrect rows with the COUNT() aggregate.
SELECT count(*) as c,
start,
UNIX_TIMESTAMP(start) as S,
duration
FROM appuntamento
WHERE DATE(start) = DATE('2014-04-08 18:30:00')
GROUP BY S
ORDER BY S DESC
LIMIT 1

I can't get mysql to return last row when using the aggregate MIN

I am using MIN function in mysql to return the smallest value of a column - lets call it price, however i also wish to display various other columns for this particular row with the smallest value for price. So far i have the following:
SELECT underlying,volatility FROM shares
where (id,price) IN (
SELECT id,MIN(price) FROM shares
where DATE(issueDate) >= DATE(NOW())
group by id
)
This almost works however it returns more than one row, i only wish to display the last row, can anyone please assist me with this?
i think i have solved the problem, it takes a while to execute so i will start by adding a new index :
SELECT underlying,volatility,price FROM shares
where (id,price) IN (
SELECT id,MIN(price) FROM shares
where DATE(issueDate) >= DATE(NOW())
group by id
) order by price asc limit 1;
SELECT underlying,volatility FROM shares
where (id,price) IN (
SELECT
SUBSTRING_INDEX(GROUP_CONCAT(id ORDER BY price ASC), ',', 1) AS id,
MIN(price) FROM shares
where DATE(issueDate) >= DATE(NOW())
group by id
)
Having clause will do the trick, please check my solution
select volatility,underlying, min(price) as min_price from shares
where DATE(issueDate) >= DATE(NOW())
group by issueDate
having min_price = min(price);
fiddle example

Mysql : find nearest Maximum value, if not find nearest minimum value

I am having db structure like this -
Table : Tasks
Columns:
TaskID, TaskDescription, TaskCreatedDate
So if I want to find TaskCreatedDate having nearest greater value to current timestamp, and if there is no any task present having greater value than current timestamp then find TaskCreatedDate having nearest smaller value to current timestamp. This should done in single query. How can I do this?
Please help. Thanks in advance
-- IN ONE GO
select t.*, coalesce( (select TaskCreatedDate from Tasks where TaskCreatedDate > t.TaskCreatedDate ORDER BY TaskCreatedDate ASC LIMIT 1),
(select TaskCreatedDate from Tasks where TaskCreatedDate < t.TaskCreatedDate ORDER BY TaskCreatedDate DESC LIMIT 1)
)
from Tasks as t
coalesce allow us to return second condition when first is null
As we do not have a piece of code to to well understand, you can try:
select *
from Tasks
order by cast([TaskDueDate] as datetime) asc
CAST or CONVERT convert explicit a value form one data type to another.
This requires a clever order by clause:
select *
from tasks
order by TaskCreatedDate > now() desc,
(case when TaskCreatedDate > now() then TaskCreatedDate end) asc,
(case when TaskCreatedDate < now() then TaskCreatedDate end) desc
limit 1;
Depending on how your types are defined, you might want to use CURRENT_TIMESTAMP instead of now().
The first clause in the order by orders future dates first, then past dates. The second puts the future dates in order by TaskCreatedDate in ascending order, so the closest one is first. If there are none, then the third comes into play, ordering the rest descending.
Grab a union of the first later-than-now task (if any), plus the last earlier-than-now task, and keep the first result.
(select TaskId, TaskDescription, TaskDueDate from Tasks
where TaskDueDate >= now()
order by TaskDueDate
limit 1)
union
(select TaskId, TaskDescription, TaskDueDate from Tasks
where TaskDueDate < now()
order by TaskDueDate desc
limit 1)
limit 1
What about this?
SELECT *
FROM Tasks
ORDER BY (CASE WHEN TIMEDIFF(TaskDueDate, CURRENT_TIMESTAMP()) > 0 THEN 0 ELSE 1 END),
(CASE WHEN TIMEDIFF(TaskDueeDate, CURRENT_TIMESTAMP()) > 0
THEN TIMEDIFF (TaskDueeDate, CURRENT_TIMESTAMP())
ELSE TIMEDIFF (CURRENT_TIMESTAMP(), TaskDueDate)
END)
That will give you all the tasks with future due dates, ordered by increasing date, followed by those with due dates in the past ordred by decreasing date. If you only want one task, add LIMIT 1 at the end