Mysql alternate week days - php

My table has the following columns
| customer_id | service_start_date |
I want to provide the service on alternate week days from the service start date (eg:- every other mondays, every other tuesdays etc..)
If the service_start_date is a monday, then the service will be delivered on every other mondays.
Is there any way to query the mysql table to get all customer_ids who needs service on a particular date?

Try something like
SELECT customer_id
FROM Table as t
WHERE MOD(DATEDIFF(DATE(NOW()), DATE(service_start_date)), 14) = 0
This is assuming that your service_start_date is always a weekday.

Addition to Clami219s answer:
To get the customer(s) that need service on a particular date (as of your request), use
SELECT customer_id
FROM table_name
WHERE
service_start_date <= NOW() AND
WEEKDAY(service_start_date) = WEEKDAY('2014-06-25'); //whatever date you like to fetch

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 |
+------------+------+

Return results per week using start date PHP

I'm trying to grab SQL data via PHP with a tally for case types each week to display like so:
Week 1 | Date From | Volume
Week 2 | Date From | Volume
Week 3 | Date From | Volume
and so on... without having to manually for each week. I have week number variables set as the business Year starts in July, so Week 1 is the first week in July. Ideally I'd like to use the company weeks but will settle for start of normal year. I've started with this:
SELECT YEARWEEK(date) as weekNum, MIN(sr_mob.`date`) as start_date,
count(*) as numRecords
FROM sr_mob
WHERE outcome='Escalated'
GROUP BY YEARWEEK(date)
This gives me the return data, but the start_date varies depending on when first entry was that week.
Is there any way to define a week in PHP then query the table (which doesn't contain the week numbers) to get what I'm after? Or does this sound like I'll manually have to request each week...
I can run a single query with say:
$Week1 ($week1=20180731-7;)
I guess what I am looking for is a way of doing a for each or while, using the $week variable, without having to write out 52 variables, if that makes sense.
Using reference from: https://stackoverflow.com/a/30373395/2397717
SELECT
YEARWEEK(date) as weekNum,
STR_TO_DATE(CONCAT(YEARWEEK(date),' Monday'), '%X%V %W') as start_date,
count(*) as numRecords
FROM sr_mob
WHERE outcome='Escalated'
GROUP BY YEARWEEK(date)

Mysql query for month to date, last month and previous month

I have a post_meta database which contains the following fields:
meta_id, post_id, meta_key, meta_value
I have created a view in PhpMyAdmin to isolate only those records with specific text to bring up a list of clients and appointment times. Each record is unique so that for a client with several appointments they would have the same name, but different time and ID. Name and time are contained in the meta_value column. Column view
Here is an example:
postID | appt_date | firstname | lastname
-----------------------------------------------
2106 | 1427698800 | Sam | Snead
2107 | 1428649200 | John | Miller
2108 | 1428476400 | Sam | Snead
My challenge is pulling both the number of appointments for the month to date, last month (e.g. Sept) and previous month ( e.g. Aug), as well as the total unique clients for the month. I am going to graph this so that the result is a column and line graph with Aug clients (column) and Aug appointments (line), sim for Sept. The MTD would be prev month plus whatever new clients and appointments so far in the month.
I not had much luck because the date is in Unix format and the month to date (which of course varies based on the day of the month). Additionally the clients show up multiple times (some of them have had 50 appointments) so selecting them only once is a challenge.
You can get this month and last month using some date() (on php side):
$this_month = date("Y-m-d");
$last_day_this_month = date("Y-m-t", strtotime($this_month));
$first_day_this_month = date("Y-m-01", strtotime($this_month));
$next_month = date("Y-m-01", strtotime($last_day_this_month." + 5 days"));
$last_month = date("Y-m-01", strtotime($first_day_this_month." - 5 days"));
Being in unix time just use date on the unix time and you will get the formatted time.
The rest is just doing some count on or group by clauses in the SQL part.
First of all you seem to want this :
you want the total number of appointments client A had in september, the same for august. Do i get that right ?
In that case you will need to figure out the right date/time to look at in your query you can do this by making use of an epoch converter such as (https://www.unixtimestamp.com/index.php)
When you found the correct epochs you can use those in your where i.e :
where appt_date < (highest epoch last day of month with time 00:00) and
appt_date > (last day of previous month time 00:00)
That isolates the time between the first and last day of the month you want to have.
For your second problem : as well as the total unique clients for the month. I would urge you to look at how to use the distinct or group by functions.
You can use the FROM_UNIXTIME() function to convert the unix timestamp to a date, and then use the MONTH() function to get the month number. Something like this:
SELECT COUNT(*) as number_of_appointments, MONTH(FROM_UNIXTIME(appt_date)) as number_month
FROM {your_view}
GROUP BY number_month
will give you the total number of appointments per month.

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.

How to Trigger total number of days in mySQL

"I need to create a field that will show the number of days between a date and the present.
TABLE: reg_add
+------------+---------+
| Name | Type |
+------------+---------+
| hm_date | date |
+------------+---------+
| total_days | date |
+------------+---------+
My client will type in the following date for example in "hm_date": May 1, 2012.
I need "total_days" to show the total days between May 1, 2012 at the current date.
I want to achieve this on server-side, which is somewhat new to me.
I need to create a TRIGGER to always have "total_days" updated
I started with this and I'm having trouble making a trigger and getting it correct:
SELECT DATEDIFF(curdate(),hm_date) as total_days FROM reg_add
Any help would be appreciated.
Erik
You can calculate it on the fly very easy, using TIMESTAMPDIFF function -
SELECT TIMESTAMPDIFF(DAY, hm_date, NOW()) FROM reg_add;
I took a look into the MySQL Trigger Docs and from the looks of it, you can only create trigger for event types Insert, Update, and Delete. So your Trigger won't actually update your total_days field (which should be int) as you want it. [It sounds like you want it to update your field on a time basis (aka every x hours update)].
Here is the docs: http://dev.mysql.com/doc/refman/5.0/en/create-trigger.html
I would suggest writing a cron job in php that runs once (or multiple times) per day that will update the field for you.
In your cron you should just have to run one sql statement: (This should go through the whole table and update the total_days field for each row)
UPDATE reg_add SET total_days = DATEDIFF(curdate(),hm_date)
Erik, I am using tsql, and not as familiar with mySQL, but in tsql the DATEDIFF function requires 3 parameters. The sytax is
DATEDIFF(date part, date1, date2).
I would try DATEDIFF(d,GETDATE(),hm_date) AS total_days FROM reg_add
Instead of triggers, you could use a View:
CREATE VIEW reg_add_with_total_days_VIEW
AS
SELECT hm_date
, DATEDIFF( CURDATE(), hm_date ) AS total_days
FROM reg_add ;
Then you can use the view, every time you need the total days - which will be calculated on the fly:
SELECT hm_date, total_days
FROM reg_add_with_total_days_VIEW
You can see it working in SQL-Fiddle

Categories