Get data by time range from Redis - php

I have MySQL table elements_info with fields:
element_id | price | time_start | time and
To get element_id and price fields from MySQL i use query:
SELECT * FROM `elements_info` WHERE 1447141365 BETWEEN time_start AND time_end;
Where 1447141365 - current timestamp.
Can I store this structure in Redis (maybe zset)?
Or maybe I should choose another NoSQL DB to get elements by time range?

Related

Grouping shifts in MySQL table by week starting with sunday using PHP & MySQL

I'm writing a script using PHP & MySQL where I can record the shifts I work (HGV driver).
Upon posting the form data PHP calculates shift duration, wages accumulated, overtime, distance driven, etc, and stores it in the MySQL database.
I want to then display all shifts in a table but group them by my pay week which unfortunately starts on a Sunday.
If the pay week was Mon-Sun I wouldn't have this problem as I could use week numbers but I can't due to the week starting on a Sunday.
My code is as follows:
^^^^^^^^^^^^^^^^^^^
// DB Connection //
// Return the earliest shift in the database //
$result = $db->query("SELECT * FROM `shifts` ORDER BY `shift_start` ASC LIMIT 1");
$data = $result->fetch_assoc();
// Establish the previous Sunday //
$week_from = strtotime(date('Y-m-d',mktime(0,0,0,date('m',$data['shift_start']),date('d',$data['shift_start']),date('y',$data['shift_start']))) . 'last sunday');
// PHP Loop Goes Here //
Firstly, is the above code the most efficient way of getting the start date (previous Sunday)?
Secondly, what's the best way to loop through the weeks where there are shifts?
TIA
This is a two part question, so I will try to cover them separately.
Regarding your first question, I would suggest using the MIN() function when selecting the smallest or earliest value in a database, and ensuring you have an index on the "shift_start" column. More information on the difference between MIN() and ORDER BY/LIMIT can be found here.
Then your query would look a something like this:
SELECT MIN(`shift_start`) FROM `shifts`;
Personally, I also find MIN() far more readable.
Now, for the other (and far more complicated) question:
You've not provided much detail on what your database (or the contents) looks like. Since you're using the PHP date function, I am assuming you're saving the timestamps as UNIX instead of MySQL TIMESTAMP/DATETIME types.
Firstly, I would suggest you migrate to using a TIMESTAMP/DATETIME column type. It'll simplify the query you're attempting to run.
If you're unable to change to a TIMESTAMP/DATETIME column, then you can convert a UNIX timestamp to a DATETIME.
MySQL has a YEARWEEK() function that you can use to group by:
SELECT STR_TO_DATE(CONCAT(YEARWEEK(`shift_start`), ' Monday'), '%X%V %W') AS `date`, SUM(`wage`) AS `wage` FROM `shifts` GROUP BY YEARWEEK(`shift_start`);
This will output something similar to:
+------------+------+
| Date | Wage |
+------------+------+
| 2021-11-29 | 50 |
| 2021-12-06 | 15 |
+------------+------+

mysql select ID where date is current date

i have this table structure:
Rows
ID | Counter | Dates
Values
1 | 100;300;44 | 01.01.2016;02.11.2016;03.03.2017
each ID is connected to an separated user.
at the moment i have 100 users, so 100 data in my table.
now i need an sql command, which show me the the ID from the user, which have a date in the Dates-Row, which is the same like the current date
This is untested, but it should be:
SELECT * FROM `table` WHERE Dates LIKE CONCAT('%',DATE_FORMAT(CURDATE(),'%m.%d.%Y'),'%');
This will select the current date CURDATE(), put it in the format you use in your table, then stick wildcards on each end so it will look inside of the string within your Dates column.

Store activity with dates

I have a structural MySQL question about storing events in a database with dates.
Say that an organiser would select a range of dates, eg:
["19/12/2014","20/12/2014","26/12/2014","27/12/2014","02/01/2015","03/01/2015","09/01/2015","10/01/2015"]
The event needs to be saved into a table, I'm thinking about creating a many-to-many table with the structure:
event_id | start_date | end_date
Now when thinking about it, this would mean that I'd need to convert the date array into an array of object with beginning - end date.
Now the alternative would be to just create a table that looks like this:
event_id | event_date
And create a separate record for every date.
The purpose is obviously to check which events should be sent back to the client within a given date range.
Which of the two options seems to common / viable?
It is pretty crucial for the setup.
Depends. If the first event ends on the date of the second event, you can go with event_id | event_date, but otherwise I'd go with the first option.
If you don't have the end date somehow, then how will you be able to tell the client the range of dates for the event?
I would go with setup that contains event duration (in seconds) - it's flexible.
event_id (int) | start_date (datetime) | duration (int)
In this case when event duration does not matter - put 0 there in other case just put the number o seconds so you will be able to store event which lasts days or just a few hours or minutes.

SQLite3 and PHP: sorting entries by datetime

I have a SQLite3 DB with entries storing sensor readings. Each row in the table looks like this:
time | temp1 | humid1 | temp2 | humid2
2013-12-07 23:15:51 | 26.06 | 16.29 | 22.24 | 17.55
where the first entry is the date, and the following ones are sensor data.
Now what I need to do is, using PHP, get the most recent 30 minutes of readings. I only want data that's less than 30 minutes old, since it's possible that data collection wasn't running and I would then get old data if I just selected the first bunch of values.
I can think of 2 ways I could do this:
Is there some way in SQLite to do something like this?
SELECT * FROM table WHERE time < (time-30 minutes)
The other thing I could do is grab the first 300 values (equivalent to 30 minutes)
and then compare the year, month, day, hour, and minute myself. The problem is, I don't know how to extract those from the PHP variable I get when I do just
SELECT * FROM table ORDER BY time DESC limit 300
So let's say I get a row (in PHP) called $row, where the time is $row['time'].
How would I go about extracting the years, months... etc. from that and comparing it to the current time?
You should be able to do something like this:
SELECT * FROM table WHERE time > datetime('now', '-30 minutes');

What are the pros and cons of the various date/time field types in MySQL?

Date and time in MySQL can be stored as DATETIME, TIMESTAMP, and INTEGER (number of seconds since 01/01/1970). What are the benefits and drawbacks of each, particularly when developing under a LAMP stack?
TIMESTAMP is stored in a MySQL proprietary method (though it's basically just a string consisting of year, month, day, hour, minutes and seconds) and additionally, a field of type TIMESTAMP is automatically updated whenever the record is inserted or changed and no explicit field value is given:
mysql> create table timestamp_test(
id integer not null auto_increment primary key,
val varchar(100) not null default '', ts timestamp not null);
Query OK, 0 rows affected (0.00 sec)
mysql> insert into timestamp_test (val) values ('foobar');
Query OK, 1 row affected (0.00 sec)
mysql> select * from timestamp_test;
+----+--------+----------------+
| id | val | ts |
+----+--------+----------------+
| 1 | foobar | 20090122174108 |
+----+--------+----------------+
1 row in set (0.00 sec)
mysql> update timestamp_test set val = 'foo bar' where id = 1;
Query OK, 1 row affected (0.00 sec)
Rows matched: 1 Changed: 1 Warnings: 0
mysql> select * from timestamp_test;
+----+---------+----------------+
| id | val | ts |
+----+---------+----------------+
| 1 | foo bar | 20090122174123 |
+----+---------+----------------+
1 row in set (0.00 sec)
mysql>
DATETIME is the standard data type for dates and times which works in conjunction with the date and time functions in MySQL. I'd probably use this in practice
Storing dates in INTEGER format is not recommended, as you are opening a real can of worms due to interesting problems like time zones, leap years and the like - at least if you intend to query the database based on specific dates stored in that field.
I would save data using the DATETIME or DATE fields in MySQL. At least, if you are going to store date values up to the year 2038: http://en.wikipedia.org/wiki/Year_2038_problem. If you're on a system that stores integers differently, you may not have this issue.
It is still easy to compare date values or even timestamps.
SELECT * FROM myTable WHERE startDate > '2009-01-01'
SELECT * FROM myTable WHERE UNIX_TIMESTAMP(startDate) > 1232541482
Well I guess the following would help clarify.
Date and time can be stored in a DATETIME field in mysql.
TIMESTAMP is used if you wish to timestamp when a row was created - the field will be automatically filled in on creation.
Using an integer for a Date is slightly overkill since this is essentially what DATETIME does but does all the time consuming conversions for you.
Is there a particular benefit or drawback you are interested in finding out about?
Timestamp in mysql can be very tricky. If not declared carefully you may end up with field that automatically changes its value on every row update (even if you dont update it explicitly).
http://dev.mysql.com/doc/refman/5.0/en/timestamp.html
If you need millisecond fidelity for a timestamp, you need to save it as an Integer. Use caution though, this can complicate things.

Categories