I am creating a REST API for a booking calendar, and right now I am trying to figure out the most efficient way of writing a query that returns all timestamps between two dates with a 15 minute interval. If I supply2013-09-21 and 2013-09-22 I would like to get:
2013-09-21 00:15:00
2013-09-21 00:30:00
2013-09-21 00:45:00
2013-09-21 01:00:00
2013-09-21 01:15:00
2013-09-21 01:30:00
...
2013-09-22 23:15:00
2013-09-22 23:30:00
2013-09-22 23:45:00
I would then use this query as a subquery and apply some conditions on it to remove timeslots outside working hours (which are not constant), booked timeslots, etc.
I have seen a lot of blog posts where the author creates a "calendar table" which stores all these timestamps, but that seems like a waste to me since that data doesn't need to be stored.
Any suggestions on how I could do this or a better way to fetch/store the data?
Here is a process that generates 95 rows incrementing a date variable as it goes and then left join the table with the dated entries to the "solid" table that has generated dated rows.
select str_to_date('2010-01-01', '%Y-%m-%d') into #ad;
select * from
(select (#ad := date_add(#ad, INTERVAL 15 MINUTE)) as solid_date from wp_posts limit 95) solid
left join
wp_posts
on solid.solid_date = post_date
I've no idea how to generate an arbitrary number of rows in mysql so i'm just selecting from a table with more than 95 rows (24 hours * 4 appointments per hour less one at midnight) -- my wordpress posts table. Nothing stopping you making just such a table and having a single column with a single incrementing integer in if there are no better ways to do it (i'm an oracle guru not a mysql one). Maybe there isn't one: How do I make a row generator in MySQL?
Where you see wp_posts, substitute the name of your appointments table. Where you see the date, substitute your start date.
The query above produces a list of dates starting 15 after midnight on the chosen day (in my example 2010-01-01)
You can add a WHERE appointments.primary_key_column_here IS NULL if you want to find free slots only
Note you didn't include midnight in your spec. If you want midnight on the first day, start the date in the variable 15 minutes before and limit yourself to 96 rows. If you want midnight on the end day, just limit yourself to 96 rows
Related
I have a MySql DB that consists of a table that holds all my data. I need to retrieve only those rows that have a startup_date that is less than or equal to today at 5 am UTC time. I tried looking up but it's kind of confusing. Can someone provide me a good, clean way of doing this?
My table is as follows:
tbl_MyData
***********
id name city startup_date
1 test1 New York 2020-01-10 18:19:30
2 test2 Houston 2019-01-30 05:00:00
3 test3 Chicago 2020-02-09 05:00:00
From the above data, my query should return ONLY row id number 2, since that is the only row that satisfies my criteria of startup_date being less than or equal to today at 5 am. Also, I'm not sure if I need to have any kind of UTC functions, since I'm not sure how mysql stores it's date time data.
Use a simple WHERE clause
SELECT t.* FROM mytable WHERE t.startup_date <= DATE_ADD(CURDATE(), INTERVAL 5 HOUR)
The CURDATE() function returns the current date without time (hence today at midnight), and the DATE_ADD() function adds 5 hours to it.
What SELECT statement have you tried also what are the data types for the table? If startup-date is a date type in MySQL then it should just be
SELECT * FROM tbl_MyData WHERE startup_date<=(whatever the value needs to be)
So let's say that I want to keep track of my CPU temperature, with simple columns 'date' and 'temperature'. I'd like to see what period saw the highest temperatures on average in the last week. I capture the data every 10 minutes, so I want each 10 minute block averaged with the same block from the other days of the week.
So for example:
2018-01-08 02:00:00 78.3
2018-01-08 03:00:00 81.2
2018-01-09 02:00:00 74.1
2018-01-09 03:00:00 75.9
I would want the averages of each day # 02:00:00, each day # 03:00:00, and so on. (except the real data is every 10 minutes) The exact datetime varies - it's not always 02:00:02, sometimes it could be 02:00:07, etc., so I can't just do an exact conditional.
Any idea how I'd go about making this data? I assume there's some way I can use GROUP BY for this, but I'm lost as to how.
Format just the hour and minute, and group by that.
SELECT DATE_FORMAT(date, '%H:%i') AS time, AVG(temperature) AS temp
FROM yourTable
GROUP BY time
This assumes that the readings are never delayed by more than a minute from the expected 10-minute periods -- if the reading for 02:10 happens at 02:11:01 it will not be put in the group.
What I am trying to achieve is grab data from the database, depending on the time.
For example, I may have multiple prices for an item, and I would like the new price to be effective based on the time and date. So I can schedule price changes in advance.
id link_id datetime price
-------------------------------------------
2 11 2016-11-03 00:00:00 1020
3 11 2016-11-03 01:00:00 1050
4 11 2016-11-03 03:00:00 1090
Let's say the time is 2016-11-03 00:59:00, when a user queries the db they will se the price-1020. But when they query the db a minute later at 2016-11-03 01:00:00 they should get price-1050.
Have tried this WHERE datetime < UTC_TIMESTAMP(), however this does not solve my problem. Also it only needs to select one entry, this selects multiple.
Is there a way MySQLi can do this?
If you are only looking for one item, I would expect something like this:
select p.*
from prices p
where p.item_id = $item_id and -- however you are representing items
p.datetime <= now() -- or UTC Timestamp if that is how the date/time is represented
order by p.datetime desc
limit 1;
I could speculate that "link_id" refers to "items".
How can I select all rows from a table where a date column is within a specific range of dates, at a given period (e.g. every 14 days)?
The table has a date column with most every date represented, possibly multiple times. The range is defined by a start date and an end date. The period is a number of days. For example:
Start: 2016-01-01 (friday)
End: 2016-12-31 (saturday)
period: 14 (days)
For the above, the query should return rows for every other Friday in 2016. That is, it should return the rows for the following dates:
2016-01-01
2016-01-15
2016-01-29
2016-02-12
2016-02-26
2016-03-11
2016-03-25
2016-04-08
2016-04-22
2016-05-06
2016-05-20
2016-06-03
2016-06-17
2016-07-01
2016-07-15
2016-07-29
2016-08-12
2016-08-26
2016-09-09
2016-09-23
2016-10-07
2016-10-21
2016-11-04
2016-11-18
2016-12-02
2016-12-16
2016-12-30
Currently, this is done in a stored procedure where a loop fills a temp table with the target dates, which is later joined on. However, I am trying to rewrite this code to step away from stored procedures.
What would be the best way to get the desired rows without using the stored procedure & a temp table? Keep in mind that (one of) the table(s) is quite large at around 1M records indexed on date, so any calculated values might impact the performance severely.
Alternatively, I could calculate all dates in the interval in PHP/RoR and use a massive IN clause, but hopefully there is a better solution.
Try this:
table_name1 is your table
date1 the date field
"2022-01-02" the start (twice included)
"2022-01-10" the end
3 the interval
SELECT date1
FROM table_name1
WHERE date1 BETWEEN "2022-01-02" AND "2022-01-10"
AND (DATE("2022-01-02") - date1) % 3 = 0;
Tested it with MySQL 5.6.
I want to delete all records in a database if the timestamp is older than 4 hours.
So my logic is to get the hour of the current time and get the hour of from the timestamp saved in the database and subtract to see if it is greater than 4. If it is greater than 4 than delete the records.
This is a code work in progress not really sure if it is correct.
DELETE FROM posts
WHERE id IN
(SELECT *
FROM posts
WHERE (HOUR(CURRENT_TIMESTAMP) - HOUR(time_published)) > 4)
)
if it makes a difference I am using MySQL.
Why not a simple
delete
from posts
where timestampdiff(hour, current_timestamp, time_published)>=4
Note that comparing the hour portions of date fields won't do what you expect. Consider comparing 21st Jan 1985 10:00 and 22nd Jan 1985 11:00. Your original condition would fail (1 hour), but it's actually 25 hours between them.
If you save the record at timestamp 1:00' and run this query at 5:59' nothing will be removed because the time difference is 4:59' and the hour component of that is 4! It might be what you want but that's way closer to 5 hours than 4.
Assuming that minutes are your smallest unit of precision, you might want to do something like
DELETE FROM posts
WHERE TIMESTAMPDIFF(MINUTE, CURRENT_TIMESTAMP, time_published) > 240
And use nested queries only when they are absolutely necessary; they possibly could slow your operations down drastically.