So, in my mysql database I am storing days and hours open in one field, called days, the data is stored in the following format:
[Monday:9:17[Tuesday:9:17[Wednesday:10:18[
As you may've guessed, it goes: [Day:From:Till and brackets are just seperatars for PHP to distinguish how many days are there.
I've been thinking all day what query would be but I could not figure out, so basically I need to get current date and time using PHP:
date(l); // Day in full text representation.
date(G); // current hour in 24 hour format.
So basically I need a query which in simple english would sound like:
SELECT all FROM businessdetails WHERE column date CONTAINS [current date] and :#:# numbers to be less than current hour and greater than current hour.
Help? My brain is melting by now.
So honestly the best thing to do is to normalize your database so you can do better queries. BUT I love to see if I can solve impossible situations so here is what you can do!
This will check all the business that are open on Tuesday at 11am
SELECT * FROM `businessdetails` WHERE `date` REGEXP 'Tuesday:(0|1|2|3|4|5|6|7|8|9|10|11):(11|12|13|14|15|16|17|18|19|20|21|22|23)[^0-9]'
(Funny thing I've found I can't seem to escape the [ in the column so I had to make sure the Regex doesn't have any extra digits at the end or it may erroneously match 2 and 20 or something.)
Here's how you can generate that REGEXP string via PHP:
<?php
$regexp = date('l') . ':(' . join('|', range(0, date('G'))) . '):(' . join('|', range(date('G'), 23)) . ')[^0-9]';
DISCLAIMER I don't actually recommend doing this but I thought it was clever and wanted to share since it directly answers your question.
EDIT
Just noticed you changed your answer. below may not apply anymore, but I'll leave it for future reference...
I would suggest having a separate child table for this.
STORES
auto increment ID
|
| the store name the store description etc..
| / / /
.--------------------------------------------------.
| id | name | description | etc |
|--------------------------------------------------|
| 1 | mary's kitchen | a fancy restaurant | etc |
| 2 | willow creek inn | we serve breakfast | etc |
'--------------------------------------------------'
STORE_HOURS
auto increment ID
| The STORES.id
| / the day (0-SUN, 6-SAT)
| _________/ / the 24h time OPEN (HH:MM:SS *TIME*)
| / _________/ ____/ the 24h time CLOSE (HH:MM:SS *TIME*)
| / / / /
.----------------------------------------------.
| id | store_id | day | time_open | time_close |
| 1 | 1 | 1 | 08:30:00 | 20:00:00 |
| 2 | 1 | 2 | 08:30:00 | 20:00:00 |
| 3 | 1 | 3 | 10:30:00 | 20:00:00 |
| 4 | 1 | 4 | 11:00:00 | 20:00:00 |
| 5 | 1 | 5 | 08:30:00 | 22:30:00 |
'----------------------------------------------'
Now, depending on what you want to display, you could query the table:
SELECT
stores.name AS store_name,
stores.description AS store_description,
store_hours.day AS store_hours_day,
TIME(store_hours.time_open) AS store_open,
TIME(store_hours.time_close) AS store_close
FROM
stores
JOIN
store_hours
ON
store_hours.store_id = stores.id
Result: http://sqlfiddle.com/#!2/e6872/8/0
With this table structure and relationship, you can then create granular queries without too much effort.
So this might be a hell of a response, but here is one way to do it... (Although I'm sure there must be more significantly better ways:
$day = date(l); // Day in full text representation.
$time = date(G); // current hour in 24 hour format.
$sql = "SELECT businessID FROM (SELECT SUBSTRING_INDEX(t_time,':',1) as start, SUBSTRING_INDEX(LEFT(t_time,POSITION('[' IN t_time) - 1), ':',-1) as end,businessID from (SELECT SUBSTRING_INDEX(SUBSTR(`column_date`,POSITION('$day' IN `column_date`) + LENGTH('" . $day . "') + 1),':',2) as t_time, businessID from `businessdetails ` where `column_date` like '%$day%') as t_table_1) as t_table_2 where start >= $time && end <= $time";
Hopefully that works =)
PS If you need help there are all these string functions you could use:
http://dev.mysql.com/doc/refman/5.0/en/string-functions.html
Related
Please accept my apologies for a lack of attempted code.
I can't get my head around this - or even figure out if it's feasible!
I have a table filled with 'date slots', these can be booked by an individual.
The time slots table looks like this:
ID | Price | Available_from | Available_ to
------------------------------------
1 | 20.00 | 2017-10-01 | 2018-01-01
2 | 20.00 | 2017-11-01 | 2017-12-07
3 | 20.00 | 2017-10-31 | 2018-01-31
4 | 20.00 | 2017-10-22 | 2017-11-21
------------------------------------
In these rows, there is a common date range where all four results are available, 2017-11-01 > 2017-11-21
I would like to query my database to see if 1) there is a common range for every result and 2) if there is, get the date range.
Desperate for help!
Thank you
I think this would work :
SELECT MAX(Available_from) as MatchFrom,
MIN(Available_to) as MatchTo
FROM Temporary.test
WHERE
(SELECT MAX(Available_from) FROM Temporary.test)
<=(SELECT MIN(Available_to) FROM Temporary.test)
It will return NULL, if there is no overlapping range.
I am trying to select data, when inserting the data it has an auto insert of the date when submitting. So when data is inserted it inserts the current date.
However, in my table I have week beginnings, so I am trying to select the data inside of that week:
mysql> select * from week;
+---------+------+------------+
| week_id | week | date |
+---------+------+------------+
| 1 | 1 | 2014-12-29 |
| 2 | 2 | 2015-01-05 |
| 3 | 3 | 2015-01-12 |
| 4 | 4 | 2015-01-19 |
| 5 | 5 | 2015-01-26 |
| 6 | 6 | 2015-02-02 |
| 7 | 7 | 2015-02-09 |
| 8 | 8 | 2015-02-16 |
| 9 | 9 | 2015-02-23 |
| 10 | 10 | 2015-03-02 |
| 11 | 11 | 2015-03-09 |
| 12 | 12 | 2015-03-16 |
| 13 | 13 | 2015-03-23 |
| 14 | 14 | 2015-03-30 |
| 15 | 15 | 2015-04-06 |
| 16 | 16 | 2015-04-13 |
| 17 | 17 | 2015-04-20 |
e.g.
select * from table where date='2015-04-06';
However the data will not be selected and presented because the inserted date was 2015-04-10. The only way to retrieve that data is by doing this:
select * from table where date='2015-04-10'; < when the data was inserted
So my question is, is it possible to select that data from that week beginning?
So if I select data from 2015-04-06 it should show data from the range of 2015-04-06 to 2015-04-12, is that possible?
Hopefully I have explained correctly, been a bit tricky to explain let alone try to implement. I can add any more info if needed.
NOTE: I am trying to use this inside of PHP so where the date is I would just use a variable, just thought I would say.
As the week will always end 6 days from the beginning you can use the between operator and the date_add function like this:
(for your specific example):
select *
from table
where date between '2015-04-06' and date_add('2015-04-06', interval 6 day)
And using a php variable:
select *
from table
where date between '$name_of_dt_var' and date_add('$name_of_dt_var', interval 6 day)
You could also compare the week of the date the data was entered with the weeks in the week table using WEEK() function.
Assuming that week is the same value as week(), the:
select t.*
from table t
where week = week('2015-04-10');
Even if the numbers do not match, then presumably you have some base date (such as 2015-01-01 and simple arithmetic would accomplish something very similar).
I have found that the most robust way to do this sort of week processing is to truncate each date in the table (in your example 2015-04-10) to the preceding Monday at midnight. That way you can compute the week of each item by assigning it to the first day of that week.
This little formula returns the preceding Monday given any DATE or DATETIME value.
FROM_DAYS(TO_DAYS(datestamp) -MOD(TO_DAYS(datestamp) -2, 7))
For example,
set #datestamp := '2015-04-10'
SELECT FROM_DAYS(TO_DAYS(#datestamp) -MOD(TO_DAYS(#datestamp) -2, 7))
yields the value 2015-04-06.
So, if you have a table called sale you can add up sales by week like this:
SELECT SUM(amount) weekly_amount,
FROM_DAYS(TO_DAYS(datestamp) -MOD(TO_DAYS(datestamp) -2, 7)) week_beginning
FROM sale
GROUP BY FROM_DAYS(TO_DAYS(datestamp) -MOD(TO_DAYS(datestamp) -2, 7))
This is a very convenient way to handle things, because it's robust over end-of-year transitions. The WEEK() function doesn't work quite as well.
If your business rules say that your weeks begin on Sunday rather than Monday, use -1 rather than -2, as follows.
FROM_DAYS(TO_DAYS(datestamp) -MOD(TO_DAYS(datestamp) -1, 7))
I'm looking for something like the person here was lookin for, only I'd like to use MySQL. The table below is something you'd find in my database (simplified).
+------+------+------+------+
| id | name | first| last |
+------+------+------+------+
| 1 | John | 1020 | 0814 |
| 2 | Ram | 0827 | 0420 |
| 3 | Jack | 0506 | 0120 |
| 4 | Jill | 0405 | 0220 |
| 5 | Zara | 1201 | 1219 |
+------+------+------+------+
First of all the entry has to be random, not id 4 and I only want 1 entry. I worked that out: SELECT * FROM test WHERE id <> 4 ORDER BY rand() LIMIT 1.
In this table the columns 'first' and 'last' are dates formatted as mmdd (both integers). So John is available for most of the year; from October 20th to August 14th. Zara on the other hand is only available for a small period of time; December 1st till December 19th.
My question: how do I change my query to only select the available people? I can't use 'between' since, in John's case, there's nothing between 1020 and 0814.
I just can't figure it out, there's must be other people that have a similar problem... Does anyone have a solution?
Kind regards
You need to distinguish two cases.
When first < last, the dates are in the same year. You can then use between to match dates.
When first > last, it means last is in the next year. In this case, the dates that match are date >= first OR date <= last.
So your WHERE clause should be:
WHERE IF(first < last, #date BETWEEN first AND last,
#date >= first OR date <= last)
I am not really sure how to explain this, but basically what I am trying to do is get the average time that it takes between a set of dates. This is what the database table looks like
id | offer_id | user | date | date_completed
----------------------------------------------------
1 | 123 | test | 1352265988 | 1352265995
2 | 123 | admin| 1352266004 | 1352266022
3 | 123 | kira | 1352264754 | 1352271946
I need to get the average time between the 2 timestamps and calculate them together so I can echo it out in my code. I am sure this would be done with a foreach statement, but I have no idea how to go about doing it. If there is anyone that can point me in the right direction that would be great!
Unless I'm missing something, you can just do it in a single query:
SELECT AVG(date_completed - date)
FROM myTable
Use the SQL-function AVG for each of the colums (date and date_completed). Than, you can just substract each average time and you will get your result you are searching for.
I'm new at this so if you think this has been answered and could point me to the right article that would be great, I've looked, and I haven't found an answer, maybe it's just taken as given, who knows.
I'm trying to retrieve the next three times in a mysql table that occur after now for a given row.
e.g. a row looks something like this in the table.
IdNum , time1, time2, time3, time4, time5, time6, time7, etc.
if the current time is say 5:22 and it corresponds to a time after time3 but before time4, how can I query the table so that I get time4, time5 and time6, but not time7, time8 etc.
Thanks for taking the time to read my problem.
EDIT:
The table would be in the format as follows (where I have condensed it, there's going to be up to 100 columns, and probably as many rows)
| IdNum | Time1 | Time2 | Time3 | Time4 | Time5 | Time6 |
---------------------------------------------------------
| 1 | 3:22 | 4:10 | 5:10 | 6:25 | 7:23 | 8:24 |
---------------------------------------------------------
| 2 | 4:32 | 6:17 | 6:55 | 7:25 | 8:45 | 10:21 |
and so on, and then I would want to provide the query with IdNum = 2, and time = 5:22 and have it return row[0] = 6:17, row[1] = 6:55, row [2] = 7:25.
In my poorest ad-hoc, freehand, untested mysql query:
select * from table where times > 5:22 LIMIT 3
Some information you should read about with respects to MySQL:
LIMIT
Comparison Functions & Operators
note this was posted before the sample schema was posted.