I have a table that depicts future flight arrival times. After each flight arrival time has past (or expired) I would like the query to update the arrival time by inserting the next arrival time, which is usually a week from the current day/time.
Although my query doesn't yield any error messages, it doesn't have an effect on expired arrival times as it should.
Find below the query:
// The update should happen between 31 minutes to and hour after the flight has arrived.
UPDATE flightSched
SET `arrivalTime`= ADDDATE(NOW(), INTERVAL 1 WEEK)
WHERE arrivalTime BETWEEN SUBTIME(NOW(), '00:31:00')
AND SUBTIME(NOW(),'01:00:00')
ORDER BY arrivalTime ASC
Find below a simlpe version of my table:
+-------------+---------------------+
| FlightNo | arrivalTime |
+-------------+---------------------+
| ET821 | 2013-11-24 08:05:24 |
| MS838 | 2013-11-24 10:05:24 |
| H7361 | 2013-11-24 13:15:06 |
+-------------+---------------------+
If the current time is 09:45, then flight number ET821 arrival time should be updated to 2013-12-01 08:05:24, Please help me understand why this update doesn't happen?
Your update doesn't produce any results because your date range in WHERE clause is incorrect. The upper value in BETWEEN operator is less than the lower value.
According to your requirements instead of
BETWEEN SUBTIME(NOW(), '00:31:00') AND SUBTIME(NOW(),'01:00:00')
^^^^^^^
it should be at least
BETWEEN SUBTIME(NOW(), '00:31:00') AND ADDTIME(NOW(),'01:00:00')
^^^^^^^
Try it the other way
UPDATE flightSched
SET arrivalTime = arrivalTime + INTERVAL 1 WEEK
WHERE arrivalTime >= NOW() - INTERVAL 31 MINUTE
AND arrivalTime <= NOW() + INTERVAL 1 HOUR
Note: make sure that you have an index on arrivalTime column.
Here is SQLFiddle demo
Related
I have a problem with CosmosDB, which also allows some SQL queries.
I have a database that is being uploaded every hour with a new record.
I would like to fetch everything from the last day from 8PM to 8AM current day and another query from 8AM to 8PM the current day. I have a timestamp in the db in ISO format. How the potential query (or queries) would look like?
I achieved to fetch last 24h like this, but I really want to stick to the time range 8PM-8AM and then 8AM-8PM, basically two shifts. Previous one and the current one.
function getLast24hTime(){
var date = new Date();
var a = date.setHours(-24);
return a;
}
and then:
SELECT * FROM c where c.time >= udf.getLastHourTime()
tl;dr Everyday I want to fetch specific hours range from the previous day (8pm-8am) + specific hours from the current day (8am-8pm). How.
in mysql you could do
the other shift is analog
CREATE TABLE be (
`date` DATETIME
);
INSERT INTO be
(`date`)
VALUES
('2022-01-13 20:41:24'),
('2022-01-13 21:41:24'),
('2022-01-14 01:41:24'),
('2022-02-14 09:41:24'),
('2022-02-14 10:41:24');
SELECT `date` from be WHERE `date` > CURDATE() - INTERVAL 1 DAY + INTERVAL 20 HOUR
ANd `date` < CURDATE() + INTERVAL 8 HOUR
| date |
| :------------------ |
| 2022-01-13 20:41:24 |
| 2022-01-13 21:41:24 |
| 2022-01-14 01:41:24 |
db<>fiddle here
I have the following table with measured values:
datetime | water | air | conductivity | ...
2021-07-17 16:44:39 | 13,9 | 18,6 | 357 | ...
I am currently querying the values for a period of time:
SELECT * FROM kn1 WHERE datetime > TIMESTAMP(DATE_SUB(NOW(), INTERVAL 1 month)) ORDER BY datetime
Now I don't want to get every value, just the highest value of each day.
In general, I can query the highest value through
SELECT MAX(water) FROM kn1 WHERE datetime > TIMESTAMP(DATE_SUB(NOW(), INTERVAL 1 month)) ORDER BY datetime
But this way I get the highest value for the entire period. But I would like to get the highest value for each day in the period.
How can I do this?
Thanks in advance
Use GROUP BY:
SELECT DATE(datetime), MAX(water)
FROM kn1
WHERE datetime > CURDATE() - INTERVAL 1 month)
GROUP BY DATE(datetime);
Note that I modified the WHERE clause to simplify it. Presumably, you don't date about the current time, just the date, so this uses the current date. Second, there is no need for TIMESTAMP, and third, I find interval arithmetic to be simpler without additional functions.
id start_date interval period
1 1/22/2018 2 month
2 2/25/2018 3 week
3 11/24/2017 3 day
4 7/22/2017 1 year
5 2/25/2018 2 week
the above is my table data sample. start_dates will be expired based on interval and period(i.e id-1 will have due date after 2 months from the start_date, id-2 will have due after 3 weeks vice versa). period is enum of (day,week,month,year). Client can give any period of dates. let's say 25-06-2026 to 13-07-2026 like that.. I have to return the ids whose due dates falls under that period.I hope i made my question clear.
Here what i have done to resolve this. I am using mysql 5.7. I found ways to achieve this with recursive CTE's.(not available in mysql 5.7). and there is a way to achieve this by populating virtual records by using inline sub queries along with unions and its a performance killer and there is restriction of population of records.(like given in the link Generating a series of dates) I have reached a point to get results for a single date which is very easy. Below is my query(in oracle)
select id
from (select a.*,
case
when period='week'
then mod((to_date('22-07-2018','dd-mm-yyyy')-start_date),7*interval)
when period='month' and to_char(to_date('22-07-2018','dd-mm-yyyy'),'dd')=to_char(start_date,'dd')
and mod(months_between(to_date('22-07-2018','dd-mm-yyyy'),start_date),interval)=0
then 0
when period='year' and to_char(to_date('22-07-2018','dd-mm-yyyy'),'dd-mm')=to_char(start_date,'dd-mm')
and mod(months_between(to_date('22-07-2018','dd-mm-yyyy'),start_date)/12,interval)=0
then 0
when period='day'
and mod((to_date('22-07-2018','dd-mm-yyyy')-start_date),interval)=0
then 0 else 1 end filter from kml_subs a)
where filter=0;
But I need to do this for a period of dates not a single date. Any suggestions or solutions will be much appreciated.
Thanks,
Kannan
Assuming this is an Oracle question and not MySQL:
I think the first thing that you need to do is calculate when the due date is. I think a simple case statement can handle that for you:
case when period = 'day' then start_date + numtodsinterval(interval,period)
when period = 'week' then start_date + numtodsinterval(interval*7,'day')
when period = 'month' then add_months(start_date,interval)
when period = 'year' then add_months(start_date,interval*12)
end due_date
Then, using that new due_date field, you can check if the due date falls between the desired date range.
select *
from(
select id,
start_date,
interval,
period,
case when period = 'day' then start_date + numtodsinterval(interval,period)
when period = 'week' then start_date + numtodsinterval(interval*7,'day')
when period = 'month' then add_months(start_date,interval)
when period = 'year' then add_months(start_date,interval*12)
else null end due_date
from data)
where due_date between date '2018-02-25' and date '2018-03-12'
The above query checking between 2/25/18 and 3/12/18 produces the following output using your data:
+----+-------------+----------+--------+-------------+
| id | start_date | interval | period | due_date |
+----+-------------+----------+--------+-------------+
| 2 | 05-FEB-2018 | 3 | week | 26-FEB-2018 |
| 5 | 25-FEB-2018 | 2 | week | 11-MAR-2018 |
+----+-------------+----------+--------+-------------+
What difference between NOW() , SYSDATE() , CURRENT_DATE() in MySQL and where it can be used in real scenario .
I tried NOW(),SYSDATE(),Current_Date() when I insert data into a table and column datatype is TIMESTAMP all are given same date and time.
Current_date() will only give you the date.
now() give you the datetime when the statement,procedure etc... started.
sysdate() give you the current datetime.
Look at the seconds after waiting 5 seconds between now()1 sysdate()1 with the following query (scroll to the right):
select now(),sysdate(),current_date(),sleep(5),now(),sysdate();
-- will give
-- now() sysdate() current_date() sleep(5) now()1 sysdate()1
-- 6/10/2014 2:50:04 AM 6/10/2014 2:50:04 AM 6/10/2014 12:00:00 AM 0 6/10/2014 2:50:04 AM 6/10/2014 2:50:09 AM
NOW() returns a constant time that indicates the time at which the statement began to execute. (Within a stored function or trigger, NOW() returns the time at which the function or triggering statement began to execute.) This differs from the behavior for SYSDATE(), which returns the exact time at which it executes.
mysql> SELECT NOW(), SLEEP(2), NOW();
+---------------------+----------+---------------------+
| NOW() | SLEEP(2) | NOW() |
+---------------------+----------+---------------------+
| 2006-04-12 13:47:36 | 0 | 2006-04-12 13:47:36 |
+---------------------+----------+---------------------+
mysql> SELECT SYSDATE(), SLEEP(2), SYSDATE();
+---------------------+----------+---------------------+
| SYSDATE() | SLEEP(2) | SYSDATE() |
+---------------------+----------+---------------------+
| 2006-04-12 13:47:44 | 0 | 2006-04-12 13:47:46 |
+---------------------+----------+---------------------+
Current_date returns the time stamp of the client while sysdate returns the time stamp of the server. If both server and the client are on the same machine, then, the result of both commands are the same. But in case that your sever is for example in USA and your clients are in China, then, these two functions return completely different results.
I don't know about thew now(), sorry :-)
One of the major differences between sysdate() and now() recently bit me in the behind. It was the difference in the point-in-time and frequency of their execution. sysdate() is evaluated every time within the same statement--ie, in every row to which it applies. But now() will only be evaluated only once, which is at the start of query execution.
This difference isn't noticeable when there are only a few rows. But it's very significant when there are millions of rows. In RHEL7, for example, sysdate() apparently makes a costly system call, so that when there are millions of rows, using sysdate() took more than an hour, but using now() in the exact same statement took only several seconds!
This is on top of precision issues, because sysdate() will return a different value, for example, between time t and time t+50 millis.
With regard to curdate(), I was also wondering how it's different from either now() or sysdate(). The MySQL Reference says that, with regard to when and how many times it's executed, curdate() behaves like now().
Reference: MySQL 5.7 Reference - Date and Time Functions -- All of the above is described in this page. However, it's scattered on the page, so you'll have to read through the overview section as well as the reference for each function.
CURRENT_DATE() is a synonym for many other similar functions all of which provide only the date.
There is a subtle difference between NOW() and SYSDATE() which you can read up more on this official MySQL website page.
CURRENT_DATE is static and works better with date indexes.
NOW() seems dynamic and does not benefit from index. (I would love to hear a comment on the subject with more detail on the MySQL internals here!)
Here's a real-world example using NOW():
explain SELECT DISTINCT e.manager_id, m.manager_name FROM events e JOIN manager m ON m.manager_id = e.manager_id
WHERE m.manager_name != '' AND e.event_when > NOW() - INTERVAL 1 YEAR;
+---------+----------+------------------------------+
| rows | filtered | Extra |
+---------+----------+------------------------------+
| 1333648 | 29.06 | Using where; Using temporary |
| 1 | 90.59 | Using where |
+---------+----------+------------------------------+
You can see the number of rows are reduced substantially using CURRENT_DATE (or CURRENT_TIMESTAMP):
explain SELECT DISTINCT e.manager_id, m.manager_name FROM events e JOIN manager m ON m.manager_id = e.manager_id
WHERE m.manager_name != '' AND e.event_when > CURRENT_DATE - INTERVAL 1 YEAR;
+--------+----------+----------------------------------------+
| rows | filtered | Extra |
+--------+----------+----------------------------------------+
| 361470 | 100.00 | Using index condition; Using temporary |
| 1 | 90.59 | Using where |
+--------+----------+----------------------------------------+
NOW() returns a constant time that indicate's the time at which the statement began to exicute whereas SYSDATE () returns the time at which it exicute... OR in other words NOW ()shows query exicution time and SYSDATE() shows self exicution time..
I have a table as -
test_table(booking_id, booking_description, start_date, end_date)
Sample Data -
1 | Some booking | 06/30/2013 | 08/01/2013
2 | Some new one | 08/05/2013 | 09/01/2013
3 | Some new two | 09/03/2013 | 09/05/2013
Now I want to generate a monthly xml file from using some java code (No problem in it, I would write), I would be passing the month and year (basically start and end date of the month) to mysql query and I want some table as -
month = 7, year 2013
1 | Some booking | 07/01/2013
1 | Some booking | 07/02/2013
...
Month = 9, year = 2013
2 | Some new one | 09/01/2013
| | 09/02/2013
3 | Some new two | 09/03/2013
...
I was looking to use a java loop from start date to end date and query mysql to find out whether this date comes in the date range or not, if it comes I would add the details else I would add blanks. But that is going to be horrible approach (will go for 30 times mysql look ups) and I am considering it as last option.
Is there any other way around with one or two mysql query and get the data in the format.
EDIT:
month = 7, year = 2013
Select *
from booking_details
where month(start_date) <= 7 and year(start_date) <= 2013 and
month(end_date) >= 7 and year(end_date) >= 2013
I developed this query but still not sure would it over all the possible scenarios.
Based on my understanding of the question you want something like this:
declare #date datetime
Select booking_id, booking_description, start_date --you don't indicate which date field you want in the results
from test_table
where (start_date between #date and date_add(#date, INTERVAL 1 MONTH))
or (end_date between #date and date_add(#date, INTERVAL 1 MONTH))
SQL is probably not exact, I know TSQL not MySQL but this should be close.