Different select query based on the day of week? - MySQL - php

Is it possible to execute a different select query for each day of the week. I currently have the following columns: id, station_name, week_type and service.
The week_type is an enom value with the following options: 'Mon-Thur', 'Fri', 'Sat', 'Sun', 'Special'.
The service column only has a varchar value of the time of day. It needs to apply as the service operates the same on a weekly schedule depending on the week_type.
+-----------------------------------+------------+-----------+-----------+
| id |station_name| week_type | service |
+-----------------------------------+------------+-----------+-----------+
| 1 | Station1 | Mon-Thur | 08:15:00 |
| | | | |
| 2 | Station2 | Sat | 10:15:00 |
+-----------------------------------+------------+-----------+-----------+
As seen in the table above, when it is Saturday in my timezone and is equal to the week_type, then it should only show Saturday rows. And etc. for the other columns.
Any help would be much appreciated, as I am new to SQL.

I think you really need to work out on the table. Why don't you normalize your table.
station_services
id|station_name
station_working_days
id|station_id|weekday_id|working_hours
If you dont want week days as seperate table then you can hardcode from 1 as sunday to saturday as 7
station_working_days
id|station_id|weekday|working_hours
By normalising you will get all the flexibility in future too.
In case if the stations all the time have the same working hours then use the following table normalisation so that it may help you.
station_services
id|station_name|working_hours
station_working_days
id|station_id|weekday_id

Related

Group By alternative in Laravel 5.4

I have a table Schedule with 3 columns (id, ref_number, pay_date). Each ref_number has a pay_date in every month. So the table looks something like this:
id | ref_number | pay_date
-----------------------------
1 | A001 | 2018-06-29
1 | A001 | 2018-07-29
1 | A002 | 2018-06-30
1 | A002 | 2018-07-30
1 | A002 | 2018-08-30
1 | A003 | 2018-06-29
I want to fetch only the earliest record for every ref_number that have pay_date between today and a date (30 or 31 days from today). The below query works fine in Mysql (I would pass the dates dynamically later).
SELECT id,ref_number,MIN(pay_date) FROM schedule
WHERE (pay_date BETWEEN '2018-06-30' AND '2018-07-30')
GROUP BY ref_number
I know we can turn the mysql "strict" to false in Database config file and the Group By would behave as expected, but without having to change that is there any other way around this problem?
What would be the eloquent equivalent for this query? With or without groupby.
After searching for a while, I came across an answer using nested select statement and gave it a try in Laravel. It worked exactly as I wanted. Here's the sweet piece of code:
Schedule::select(DB::raw(id, ref_number, MIN(pay_date) as pay_date))
->from(DB::raw("(SELECT *
FROM schedule
WHERE (pay_date > CURDATE()))
temp")
)
->groupBy('temp.ref_number')
->get();

Best way to handle business opening time in a year PHP and MySQL

We have developed a website for pharmacies in which we show the opened pharmacies in a specific city.
I handle this with a field named "timestamps" in wich it is stored all timestamps of opening hour every 15 minutes for a period of about 3 months.
For example if every days the farmacy is open from 8:00 to 19:00 there is a range of timestamps from one time to another, with an interval of 15 minutes.
While in the frontend we have a list of opened pharmacies and I could show opened ones by querying the database with for example:
"WHERE timestamps LIKE('%1449820800%')" where the timestamp is the current time rounded to the nearest quarter hour.
The question is: considering the time ranges are different from week to week, is there a better way to handle this situation? Also because we have 25.000 users and the website is slow if we have large amount of timestamps.
Thank you in advance!
You could just have a database with each day of openning for every store :
-----------------------------------------
| StoreId | Day | HourOpen | HourClose |
=========================================
| 1 | 1 | 8:30 | 21:15 |
-----------------------------------------
| 1 | 2 | 9:00 | 17:00 |
-----------------------------------------
| 2 | 1 | 10:00 | 12:30 |
-----------------------------------------
| 2 | 1 | 14:00 | 19:00 |
=========================================
In this table, the day represent the day of the week (1 for monday, 2 for tuesday for example) and then you just have to parameter the openniong hours for each store only once.
You can then query this table to see if a store is open for a day of the week at the very moment.
If a pharmacy has an exceptionnal closure or openning hours for a day, i suggest an ovveride table like this one
----------------------------------------------------------
| StoreId | Date | isOpen | HourOpen | HourClose |
==========================================================
| 1 | 2015-12-20 | true | 10:00 | 16:00 |
----------------------------------------------------------
| 2 | 2015-12-20 | false | null | null |
==========================================================
This way, you can check first if an pharmacy has any record in this table for the current day (not depending of the time) if it does, you check if there is an opening. If there is not any entry in the override table, you check with the first table.
You also can ahve a hour model table with opening and closing time, a day table, and an associative table that creates relations between stores, hours and days.

How to go about building a daily timeslot with php and mysql?

I am currently working on a project where i was required to develop a timeslot system where employee can occupy a time slot within a specific day. I am using military time as my time format 00:00:00 - 23:00:00 and the days are from sunday - saturday. I just want them to book times for each day.
what is the correct mysql schema for this?
How do i go about handling validation, making sure that they only book for the available timeslots.
----------------------------------------------------
USER_ID | DAY | STARTS_AT | ENDS_AT
----------------------------------------------------
| | |
| | |
| | |
| | |
| | |
------------------------------------------------------
Well I think the logic of which slot is available should be in your code, and then you simply keep record of which employee booked what time slot, using mysql datetime, don't think you need an extra day field, maybe something like id, user_id, start_time, end_time

MySQL sql query LIKE to get current opening hours

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

Get average time between several dates for one entry

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.

Categories