PHP - MySQL: Synchronize two calendars - php

I'm using a plugin for calendar bookings and reservations. I can create more calendars, but I can't set different services, prices and payment methods in one calendar.
I need two different services for the same event, so I should create two calendars, but in this case there isn't a synchronization of booking days between the calendars: I need one calendar only.
So my intention is to synchronize both the calendars via PHP and MySQL. This plugin create a specific table called "days" in the calendar db for date, like this:
| Calendar Id | Day | Month | Year |
| 01 | 01 monday available | 01 | 2014 |
| 01 | 02 tuesday available | 01 | 2014 |
| 01 | 03 wednesday booked | 01 | 2014 |
| 02 | 01 monday in pending | 01 | 2014 |
| 02 | 02 tuesday booked | 01 | 2014 |
| 02 | 03 wednesday available | 01 | 2014 |
How can I synchronize data (day, month, year) of calendar id 01 and calendar id 02?
I've found this:
How can i synchronize two database tables with PHP?
But I need to syncronize data (records) and not tables or databases.
I hope that my questione is clair, sorry for my English and thanks in advance!

You should create a new column to store if is available.
| Calendar Id | Day | Month | Year | Available
Then, you can use a trigger:
CREATE TRIGGER synchronize_update BEFORE UPDATE ON table
FOR EACH ROW BEGIN
UPDATE table SET Available = NEW.Available WHERE calendar_id <> NEW.calendar_id AND Day = New.Day And Month = NEW.Month AND Year = NEW.Year;
END;

Related

MySQL query based on highest value but column is VARCHAR

Running into a bit of a problem here. We have a system where we track our website hostings and I'm developing a frontend portal on this already pre-existing system.
In the database, the table looks something like:
id | company_id | renewal | domain_name
and an example couple entries in a MySQL database:
1 | 5 | June 2014 | www.example.com
2 | 5 | June 2015 | www.example.com
3 | 5 | June 2016 | www.example.com
4 | 5 | June 2017 | www.example.com
5 | 5 | June 2018 | www.example.com
6 | 5 | June 2014 | www.stackoverflow.com
7 | 5 | June 2015 | www.stackoverflow.com
8 | 5 | June 2016 | www.stackoverflow.com
9 | 5 | June 2017 | www.stackoverflow.com
10 | 5 | June 2018 | www.stackoverflow.com
I am wanting to SELECT * where the company_id = 5 - that's no problem. I then want to show all domains where the renewal is the highest - basically I want to return:
5 | 5 | June 2018 | www.example.com
10 | 5 | June 2018 | www.stackoverflow.com
Getting unique domains is simple, I've achieved that by GROUP BY(domain_name), but am clueless on sorting by renewal, especially because it isn't a simple int, rather a combination.
I would definitely recommend to convert this table to something with a real date in it, so you can sort it. For the time being, you could use MySQL's STR_TO_DATE function, which tries to parse the date according to a given format.
Here that would be:
SELECT domain_name, MAX(STR_TO_DATE(renewal_date, '%M %Y')) AS max_renewal_date
FROM table
WHERE company_id = 5
GROUP BY domain_name

MySQL searching through time interval

The system is as such. Tutors provide their availability (Monday - Sunday) and the time frame they are available on that day (0700 - 1400) (ie: 7am - 2pm).
I am trying to figure out the best way to store and search through this information to find available tutors. Searching only needs to be done on a daily system (ie: day of the week - mon, tues, wed, etc).
My planned infrastructure:
//Tutor Availability
---------------------------------------------------------------------------
tutorID | monday | tuesday | wednesday | thursday | friday |
---------------------------------------------------------------------------
27 | 0700-1200 | NULL | 1400-1800 | NULL | NULL |
---------------------------------------------------------------------------
35 | NULL | 1400-1600 | NULL | NULL | 1100-1900 |
//Scheduled tutor sessions
------------------------------------
tutorID | day | time |
------------------------------------
27 | monday | 0700-0900 |
------------------------------------
35 | friday | 1300-1500 |
Query: SELECT tutorid FROM tutoravailability WHERE 'monday'=... is available between 0900-1100 and is not in scheduled tutor session.
I have been searching forever about how I can search through (and store) these time intervals in MySQL. Is this the best way to store the time intervals of a 24 hours day? Will it even be possible to search between these intervals? Am I approaching this from the wrong way? Any insight is appreciated.
Updated Infrastructure
//Tutor Availability
-----------------------------------------------------
tutorID | day | start_time | end_time | PK |
-----------------------------------------------------
27 | mon | 0700 | 1200 | 1 |
-----------------------------------------------------
27 | fri | 1400 | 1800 | 2 |
-----------------------------------------------------
35 | tue | 1100 | 1600 | 3 |
//Scheduled tutor sessions
--------------------------------------------------------
tutorID | day | start_time | end_time | PK |
--------------------------------------------------------
27 | mon | 0800 | 1000 | 1 |
--------------------------------------------------------
27 | fri | 1600 | 1800 | 2 |
So with this system it will be much simpler to search for available times. However I am still at a loss as to how to compare the availability against the scheduled lessons to ensure no overlap.
SELECT tutorID
FROM tutoravailability WHERE day = 'fri'
AND start_time <= '1400'
AND end_time >= '1530'
Now I don't understand how I would compare this query against the Scheduled tutor sessions table to avoid duplicate bookings.
Final Update
To ensure their are no overlapping of the Scheduled Tutors sessions I will use the MySQL BETWEEN clause to search for the start and end time.
If you store the time interval using two columns it will be much easier for you to perform a search using sql query.
i.e. tutorID, day, startTime, endTime
You can use a bit flag to indicate the availability (24 bit) and scheduled time (24 bit). Then you can use 24 bit to represent the available hours and scheduled hours for each day.
In the Tutor Availability table, let's say '1' stands for Available in and '0' stands for unavailable. In the Scheduled table, '0' stands for Scheduled, '1' stands for Unscheduled.
So the available interval 0900-1100 can be stored as POW(2,9) | POW(2,10) | POW(2,11); the scheduled 1000-1200 can be stored as ^(POW(2,10) | POW(2,12))
Then the following query can give your the availability of on tutor - available on Monday between 09 am to 11 am:
SELECT ta.tutorid FROM tutoravailability ta, tutorscheduled ts
WHERE ta.tutorid = ts.tutorid AND ts.day = 'monday'
AND (ta.monday & ts.time & (POW(2,9) | POW(2,10) | POW(2,11))) = (POW(2,9) | POW(2,10) | POW(2,11))

Group data by date range and display query results in tabular form

I'm attempting to aggregate payment histories under a single due date and create an html table similarly displayed below.
+--------------+---------------+----------------+
| Date Due | Amount Paid | Date Paid |
+--------------+---------------+----------------+
| Nov, 1 2012 | $10 | Oct, 21 2012 |
| | $15 | Oct, 18 2012 |
| Oct, 14 2012 | $20 | Oct, 13 2012 |
| | $20 | Sep, 3 2012 |
+--------------+---------------+----------------+
The problem I am facing is this:
The date due, amount paid, and date paid data fields are all in the same table row. The date due does not necessarily correspond to when the actual payment was made (maybe a payment was made 3 weeks late). Or... maybe two payments were received within the time frame of a single payment date due.
How can I efficiently tackle a problem like this and display it in a table? I've tried a few ways already and the code is too system process intensive.
EDIT: The rows in the table of the database currently look something like this:
+--------------+---------------+----------------+
| Date Due | Amount Paid | Date Paid |
+--------------+---------------+----------------+
| Nov, 29 2012 | $10 | Oct, 21 2012 |
| Nov, 15 2012 | $15 | Oct, 18 2012 |
| Nov, 1 2012 | $20 | Oct, 13 2012 |
| Oct, 14 2012 | $20 | Sep, 3 2012 |
+--------------+---------------+----------------+
But the customer has to pay $50 for every due date. In this case, the customer split up their payments and it did not apply to the current due date because of the way the data is formatted in the table.
Unfortunately, I can not change anything in the database.
The query will be
select * from table_name order by Date_Due ASC,Date_Paid ASC , Amount_Paid ASC
This query first do order by of Date_Due by ascending and after that by Date_Paid and Amount_Paid.
Assuming your query is on a single flat table, it sounds like you simply want each due date to display only once (instead of with every row).
If thats correct, I think you should just approach the problem in your php code that constructs your table rather than trying achieve this in your mysql result.

PHP / MySQL select by DATETIME field across DST change

Please forgive me if this unclear, but I am having a tough time trying to get what is in my mind down on paper.
Scenario:
We store a variety of jobs in a table. These are all timestamped using DATETIME set to UTC time zone.
Our users may have their timezones set in their preferences, so that we can transcribe system times to the users local times.
Now, assume that a user goes to select all jobs that were entered on October 25, 2012 (local user time):
+--------------------------------------+------------+---------+---------------------+
| id | project_id | amount | created |
+--------------------------------------+------------+---------+---------------------+
| 50889ba5-77b4-41e1-a942-1dea0ab761f6 | 15076850 | 50.00 | 2012-10-25 01:53:41 |
| 5088b9a3-8110-446e-81c8-75da341f3f95 | 15076850 | 2000.00 | 2012-10-25 04:01:39 |
| 5088c852-d434-41e6-ba5d-27560ab761f6 | 15076850 | 100.00 | 2012-10-25 05:04:18 |
| 50892a3b-ad9c-4a32-aebf-384c0ab761f6 | 15076850 | 500.00 | 2012-10-25 12:02:03 |
| 50893098-6b9c-4028-9a87-3eb20ab761f6 | 15076850 | 25.00 | 2012-10-25 12:29:12 |
| 50894b10-d260-4f61-8eb9-1d190ab761f6 | 15076850 | 25.00 | 2012-10-25 14:22:08 |
| 50895129-48c8-4bb4-928f-483b341f3f95 | 15076850 | 25.00 | 2012-10-25 14:48:09 |
| 50896019-7144-4e74-8037-4160341f3f95 | 15076850 | 50.00 | 2012-10-25 15:51:53 |
+--------------------------------------+------------+---------+---------------------+
8 rows in set (0.00 sec)
If this user is in the Eastern United States (EST), and the times in this table are UTC, the results are going to come across as October 24th for the first two rows in the table results. Basically, I want to exclude those first two rows if the user is EST.
I have been experimenting with the use of DateTime(), however - I am stuck because this spans DST end (November 4, 2012). When I select the date on October 25th, DST is active, so it shows the users local time as UTC -0400. When the job ends, it is after (UTC -0500).
I am completely stuck on how to make this work.
Get the UTC timestamp for what is the user's midnight (which is 4am UTC in the below example):
$start = new DateTime('2012-10-25 00:00:00', new DateTimeZone('America/New_York'));
$start->setTimeZone(new DateTimeZone('UTC'));
$start = $start->format('Y-m-d H:i:s');
// do the same with $end
SELECT ... WHERE `created` BETWEEN $start AND $end
The final query should select WHERE BETWEEN 2012-10-25 04:00:00 AND 2012-10-26 03:59:59, which is the day of October 25th in America/New York.
This should also work during DST changes. On November 4th, the query would be BETWEEN 2012-11-04 04:00:00 AND 2012-11-05 04:59:59, encompassing one more hour.

CROSSTAB REPORT - MYSQL

I want generate a HTML report, using PHP and the following Mysql data:
VIDEOS
id | title
01 | video1
02 | video2
03 | video3
04 | video4
JURORS
id | Name
01 | juror1
02 | juror2
03 | juror3
REVIEWS
id_video | id_juror | grade
01 | 01 | 5,2
02 | 01 | 4,5
03 | 01 | 2,7
04 | 01 | 7,0
01 | 02 | 3,2
02 | 02 | 9,6
03 | 02 | 4,7
04 | 02 | 8,3
The OUTPUT should be something like that:
| juror1 | juror2 | juror3
video1 | 5,2 | 3,2 | NULL
video2 | 4,5 | 9,6 | NULL
video3 | 2,7 | 4,7 | NULL
video4 | 7,0 | 8,3 | NULL
I have tried many different querys and crosstab tutorials, but they would use CASE for a limited quantity of videos and jurors, but I need it to be dynamic.
In MySQL, you can't do this with just a query. One approach, described at http://www.databasejournal.com/features/mysql/article.php/3871556/article.htm, is to create a stored-procedure that finds all the possible videos and all the possible jurors and then dynamically builds a SQL query. But since you're writing in PHP, I think you'd find it easier to do that in PHP than in a stored procedure. Alternatively, you can run a straightforward SELECT videos.title, jurors.name, reviews.grade FROM reviews JOIN videos ON videos.id = reviews.id_video JOIN jurors ON jurors.id = reviews.id_juror and handle the translation in PHP.
Using MySQL Pivot table generator you can do this report instantly .
You will be asked to enter the data source of your columns , Rows and Values of your report .
In the columns : You select the JURORS table and the name column as in the following screenshot:
Similarly you should select the Videos table and Title column as the data source for the rows then finally the reviews table and grade column for the values and you get your report , which will be fed automatically from your database
For more information you can check the following tutorial :
http://mysqlpivottable.net/Tutorial.html

Categories