I am trying to write a query that detect when a reservation is in the last 15 mins of it (so it knows it's nearly done). So as of now I have:
UPDATE bookings b JOIN reservation_time_data r ON r.id = b.reservation_time SET b.reservation_processed = 'ending' WHERE reservation_date LIKE ? AND CURRENT_TIME BETWEEN(r.end_time AND r.end_time - '00:15:00.000000')
Usually for adding time I would use ADDTIME() but for this I'm not sure.
You could phrase this as:
where
reservation_date like ?
and r.end_time between current_time - interval 15 minute and current_time
Related
I am not so into database and I have the following problem working on this MySql query:
SELECT
CCMD.id AS crop_calendar_message_details_id,
CCMD.broadcasting_start_date AS broadcasting_start_date,
CCMD.broadcasting_end_date AS broadcasting_end_date,
CCMD.creation_date AS creation_date,
CCM.id AS message_id,
CCM.content_en AS content_en,
IFNULL(CCMN.content, CCM.content_en) AS content,
CCMN.audio_link AS audio_link,
CCMD.crop_action_details_id AS crop_action_details_id
FROM CropCalendarMessageDetails AS CCMD
INNER JOIN CropCalendarMessage AS CCM
ON CCMD.crop_calendar_message_id = CCM.id
LEFT JOIN CropCalendarMessageName AS CCMN
ON CCMN.crop_calendar_message_id = CCM.id AND CCMN.language_id = :language_id
INNER JOIN CropActionDetails AS CAD
ON CCMD.crop_action_details_id = CAD.id
WHERE
CCMD.commodity_id = 10
AND
CCMD.country_id = 2
AND
CAD.id = :cad_id
AND
CCMD.broadcasting_start_date >= CURDATE()
AND
CURDATE() <= CCMD.broadcasting_end_date
ORDER BY CCMD.broadcasting_start_date
I have some records that have the following fixed values for thes date fields:
CCMD.broadcasting_start_date = 22/12/2018 23:59:00
CCMD.broadcasting_end_date = 30/05/2018
So in theory my query should skip these values because I have set this section on my WHERE clause:
AND
CCMD.broadcasting_start_date >= CURDATE()
AND
CURDATE() <= CCMD.broadcasting_end_date
The problem is that these records are returned by my query so this dates filter condition is not working.
Why? What is wrong? What am I missing? How can I fix it?
When dealing with date/time values and querying, I personally have always tried to apply >= and < the boundaries. For example, if you wanted something for All activity within March, 2018, I would do
where '2018-03-01' <= DateTimeField
AND DateTimeField < '2018-04-01'
By doing greater or equal to the start of just a date, you get from midnight all the way through the date period. As for the ending date, I always go LESS than the following day (hence April 1st). So I get everything up to Mar 31 at 11:59:59pm.
This way you also dont need to mess with date conversion functions just to ensure something is on the same day or time-portions thereof.
Might this help in resolving the date/time considerations of your query.
I am relatively new to SQL, i am trying to update monthly salary based on employees working for a certain duration, the query displays the data using info from the person and employee table but it won't update, i keep getting a 'operand should contain 1 column' error? How would i go about displaying all the data and be able to update the monthly_salary column as well? Thanks.
UPDATE employee ep set monthly_salary = monthly_salary*1.15 = all(
SELECT p.person_id, p.name_first, p.name_last, ep.monthly_salary, ep.start_date, curdate() as today_date,
TIMESTAMPDIFF(month,ep.start_date,curdate()) as duration_months
FROM employee ep
INNER JOIN person p ON ep.person_id = p.person_id having duration_months > 24);
query result
I want this expected result but the monthly salary hasn't been updated yet, is it possible to display this and update the monthly_salary?
You are not able to do both in a single query. Typically one would run a "select query" to inspect if the desired logic appears correct, e.g.
SELECT
p.person_id
, p.name_first
, p.name_last
, ep.start_date
, curdate() as today_date
, TIMESTAMPDIFF(month,ep.start_date,curdate()) as duration_months
FROM employee ep
INNER JOIN person p ON ep.person_id = p.person_id
WHERE ep.start_date < curdate() - INTERVAL 24 MONTH
;
In that query the important piece of logic is the where clause which seeks out any employees with a start date earlier than today - 24 months.
If that logic is correct, then apply the same logic in an "update query":
UPDATE employee ep
SET monthly_salary = monthly_salary*1.15
WHERE ep.start_date < curdate() - INTERVAL 24 MONTH
;
Syntax notes:
you cannot string multiple conditions together using multiple equality operators (monthly_salary = monthly_salary*1.15 = all(...) there are 2 = signs in that
x = all() requires that all values returned by a subquery will equal x
the having clause is NOT just a substitute for a where clause. A having clause is designed for evaluating aggregated data e.g. having count(*) > 2
Finally, while it was inventive to use the having clause, what you were doing was gaining access to the alias 'duration_months', so you could simply have done this instead:
where TIMESTAMPDIFF(month,ep.start_date,curdate()) > 24
BUT this is not a good way to filter information because it requires running a function on every row of data before a decision can be reached. This has he effect of making queries slower. Compare that to the following:
WHERE ep.start_date < curdate() - INTERVAL 24 MONTH
ep.start_date is not affected by any function, and curdate() - INTERVAL 24 MONTH is just one calculation (not done every row). So this is much more efficient (also known as "sargable").
I am trying to figure out whether my current time falls between two given times. It is working fine, unless if my end time falls after the mid night, while my start time is during the day.
For example, if I have:
Start: 17:00
End: 03:00
Current: 18:30
It then will not show up.
I do understand where the logic is going wrong, but I can't find a fix for it, logically and conceptually. I mean, you could claim that 06:30 PM does fall between 05 PM and 03 AM, but then 03 AM of the next day!
How do we overcome that problem?
Here is my query below:
SELECT * FROM products
JOIN restaurants
ON (products.Venue = restaurants.name)
WHERE products.Drink_Category = Beer
AND restaurants.Area = Racks
AND (
HOUR(18:30) >= HOUR(products.Start) -- here is where the time is set
AND HOUR(18:30) <= HOUR(products.End) --and here is the end
)
ORDER BY products.Price/products.Multiple ASC;
I have as well tried BETWEEN query, and yet it does not work for those specific cases.
Basically, when products.End is smaller than products.Start, just add 24 to account for the day wrapping. E.g.
SELECT * FROM products
JOIN restaurants
ON (products.Venue = restaurants.name)
WHERE products.Drink_Category = Beer
AND restaurants.Area = Racks
AND (
HOUR(18:30) >= HOUR(products.Start) -- here is where the time is set
AND HOUR(18:30) <= CASE
WHEN products.End<products.Start
THEN HOUR(products.End)+24
ELSE HOUR(products.End) END --and here is the end
)
ORDER BY products.Price/products.Multiple ASC;
you have 2 way:
1- use complete date time value in your Condition like this:
Select * FROM table_event where ((SaleDate >= #FromDate) AND (SaleDate < #ToDate)) Order by SaleDate DESC
2- you can change your condition in back end, if your end time go to tomorrow you must write another condition like this:
(HOUR(18:30) >= HOUR(products.Start) AND HOUR(23:59) <= HOUR(products.End) )
OR
( HOUR(00:00) >= HOUR(products.Start) AND HOUR(3:00) <= HOUR(products.End) )
For a room reservation page I'm making a query for entries among 3 tables. Datetime values are in one table, another table keeps the info if the room key has been checked out. And another table keeps the reservation information. If current time has past start of reservation time at least 15 minutes and the key has not been checked out, the entry should get deleted. Problem is, it deletes also future reservations, where the start time of the reservation has not past yet. My query looks like this.
SELECT dt.field_reservation_datetime_value
, dt.entity_id
, co.field_reservation_checked_out_value
, co.entity_id
, res.reservation_id
FROM field_data_field_reservation_datetime dt
JOIN field_data_field_reservation_checked_out co
ON co.entity_id = dt.entity_id
JOIN studyroom_reservation res
ON res.reservation_id = co.entity_id
WHERE co.field_reservation_checked_out_value = 0
AND DATE (dt.field_reservation_datetime_value) <= NOW() - INTERVAL 15 MINUTE
Right now it is 9:52am, this shouldn't be showing up for the next 2 hours and 38 minutes. What I get is this:
Any idea what I may doing wrong?
edit: table alias added and screenshot
Solved it with following code
SELECT dt.*, co.*, res.*
FROM field_data_field_reservation_datetime AS dt
JOIN field_data_field_reservation_checked_out AS co
ON co.entity_id = dt.entity_id
JOIN studyroom_reservation as res
ON res.reservation_id = co.entity_id
WHERE co.field_reservation_checked_out_value = 0
AND ((dt.field_reservation_datetime_value)
<= DATE_FORMAT(NOW() - INTERVAL 15 MINUTE,'%Y-%m-%d %H:%i:%s'))
I have a table with 3 days of data (about 4000 rows). The 3 sets of data are all from a 30 minutes session. I want to have the start and ending time of each session.
I currently use this SQL, but it's quite slow (even with only 4000 records). The datetime table is indexed, but I think the index is not properly used because of the conversion from datetime to date.
The tablelayout is fixed, so I cannot change any part of that. The query takes about 20 seconds to run.. (and every day longer and longer). Anyone have some good tips to make it faster?
select distinct
date(a.datetime) datetime,
(select max(b.datetime) from bike b where date(b.datetime) = date(a.datetime)),
(select min(c.datetime) from bike c where date(c.datetime) = date(a.datetime))
from bike a
Maybe I'm missing something, but...
Isn't the result returned by the OP query equivalent to the result from this query:
SELECT DATE(a.datetime) AS datetime
, MAX(a.datetime) AS max_datetime
, MIN(a.datetime) AS min_datetime
FROM bike a
GROUP BY DATE(a.datetime)
Alex, warning, this in typed "freehand" so may have some syntax problems. But kind of shows what I was trying to convey.
select distinct
date(a.datetime) datetime,
(select max(b.datetime) from bike b where b.datetime between date(a.datetime) and (date(a.datetime) + interval 1 day - interval 1 second)),
(select min(c.datetime) from bike c where c.datetime between date(a.datetime) and (date(a.datetime) + interval 1 day - interval 1 second))
from bike a
Instead of comparing date(b.datetime), it allows comparing the actual b.datetime against a range calculated form the a.datetime. Hopefully this helps you out and does not make things murkier.