How to check the id is booked of for specific days? - php

I have a table and records are like below table.
id | list_id |venue_id |name | start_date | end_date |start_time |end_time | days
1 | 1 | 1 |asdf | 2019-02-02 14:05:54| 2019-02-28 14:05:54|05:30 |10:00 | 1,2,3
2 | 7 | 2 |awed | 2019-02-10 15:02:24| 2019-02-20 15:02:24|07:30 |14:00 | 2,5
3 | 7 | 1 |mjgd | 2019-02-04 09:05:54| 2019-02-13 09:05:54|09:30 |18:00 | 4
Now What I am doing is I have to check the start_time and end_time range if found in the range then check start_date and end_date are in the range if found then display the records.
So below query is working for the above scenario
SELECT * FROM batch_list
WHERE venue_id=1 AND (start_date <= '2019-03-01') AND (start_time <= '13:00:00') AND (end_date >= '2019-02-04') AND (end_time >= '10:00:00')";
Now I have one more column which is days. So what I am doing is venue_id=1 is booked for a day which is 1,2,3,4 then display the records.
So how do i check the days which is already booked for id 1?
So what query I have to the user it to check the days are already in the table or not of the venue id=1?
function fetchBatches($venue_id,$new_batch_start_date,$new_batch_end_date,$new_batch_start_time,$new_batch_end_time,$days)
{
$where="venue_id=$venue_id AND (start_date <= '$new_batch_end_date') AND (start_time <= '$new_batch_end_time') AND (end_date >= '$new_batch_start_date') AND (end_time >= '$new_batch_start_time')";
$result =$this->db->select('*')
->from('batch_list')
->where($where)
->get()
->result();
if ($result) {
return $result;
}
else{
return 0;
}
}
Would you help me out on this issue?

A query to check whether one range overlaps another might look like this:
SELECT x.*
FROM my_table x
WHERE x.start_datetime < :end_datetime
AND x.end\datetime >= :start_datetime;
But really your question is broader than this

Related

How to find the start_time and end_time range if found in the range then check start_date and end_date

I have a below table in the database.
id | list_id |venue_id |name | start_date | end_date |start_time | end_time
1 | 1 | 1 |asdf | 2019-02-02| 2019-02-28 |05:30 |10:00
2 | 7 | 2 |awed | 2019-02-10| 2019-02-20 |07:30 |14:00
3 | 7 | 1 |mjgd | 2019-02-04| 2019-02-13 |09:30 |18:00
Now, I have to find the start_date and end_date of venue_id=1 between the range of 2019-02-04 and 2019-03-01. So I used below query.
SELECT * FROM `batch_list` WHERE `venue_id` = 1 and ((start_date between '2019-02-04' and '2019-03-01') OR (end_date between '2019-02-04' and '2019-03-01'))
Now I have to find the date and time of the venue_id=1 which is a range of 2019-02-04 and 2019-03-01 and 05:00 to 18:00. So I tried below query
SELECT * FROM `batch_list` WHERE `venue_id` = 1 and ((start_date between '2019-02-04' and '2019-03-01') OR (end_date between '2019-02-04' and '2019-03-01')) and((start_time <= `end_time`) and (`start_time` between '05:00' and '18:00')and (end_time between '05:00' and '18:00'))
So there is no issue till now.
I have a time which is 05:00 to 20:00 then I am getting the all the records with related to the venue_id 1 but If I change the time 10:00 to 13:00 then I am not getting the records.
I need to find out the is there any start_time and end_time is available in the range or not. If found then check the start_date and end_date.
Would you help me out in this issue?
Model
function fetchBatches($venue_id,$new_batch_start_date,$new_batch_end_date,$new_batch_start_time,$new_batch_end_time)
{
$where="batch_venue_id='$venue_id' and ((start_date between '$new_batch_start_date' and '$new_batch_end_date')OR (end_date between '$new_batch_start_date' and '$new_batch_end_date')) and ((start_time<=end_time) and (start_time < '$new_batch_start_time' and start_time < '$new_batch_end_time'))";
$result =$this->db->select('*')
->from('batch_list')
->where($where)
->get()
->result();
if ($result) {
return $result;
}
else{
return 0;
}
}
As some people suggested, it's better to combine date and time into the database.
For your question, I think that the query you want is this one:
SELECT * FROM batch_list
WHERE venue_id = 1
AND (start_date <= '2019-03-01')
AND (start_time <= '13:00:00')
AND (end_date >= '2019-02-04')
AND (end_time >= '10:00:00')

Get the count of users before 90 days records from the e_date

Database table i have:
S.no | j_id |age | e_date |
-------------------------------------
1 | 1 |32 | 2018-05-09 |
-------------------------------------
-------------------------------------
1 | 1 |32 | 2018-05-09 |
-------------------------------------
-------------------------------------
1 | 2 |32 | 2018-05-09 |
-------------------------------------
-------------------------------------
1 | 2 |32 | 2018-04-16 |
-------------------------------------
-------------------------------------
1 | 1 |32 | 2018-09-16 |
-------------------------------------
-------------------------------------
1 | 3 |32 | 2018-04-16 |
------------------------------------
In my table I have expiry date I want to get the count of the result whose expiry date (90 days before) is equal to current date.
like I have expiry date 2018-05-09 and current date is 2018-02-2018 (90 days before date ) now i want to get to the count of the 90 days before result by query.
select * from yourtable
where datediff(CURDATE(), e_date) > 90
try to use datediff to get the different date count in day. Hope that this is what you want to get.
I like to keep the logic on the PHP side as much as possible, so I would probably calculate my expiry date in PHP and just add a simple where to the query. In Laravel that could look something like this:
$expireTreshold = Carbon::now()->addDays(90);
$expireCount = $myModel->where('e_date', '<=', $expireTreshold)->count();
For getting the current date, you can use CURDATE(), CURRENT_DATE(), and NOW() any one of these functions would get the current date. While the DATEDIFF() will get the difference between two periods (start date to end date).
If you only need to get the expiry dates that fit the 90 days condition use this :
SELECT e_date
FROM tableName
WHERE
e_date >= NOW()
AND datediff(e_date, NOW()) <= 90
In the query, you're scanning for future dates (from the current date and forward) and then get the differences, if the differences is less than or equal to 90 days, then it'll be selected.
if you need to show how many days left to each user:
SELECT sno, datediff(e_date, NOW())
FROM test
WHERE
e_date >= NOW()
AND datediff(e_date, NOW()) <= 90
It will work fine.
SELECT count(*) FROM table WHERE e_date < CURDATE() - INTERVAL 90 DAY;
OR
SELECT count(*) FROM table WHERE e_date < NOW() - INTERVAL 90 DAY;
cheers :)
Try this:
$your_date = "2018-01-01";
query = 'SELECT COUNT(*)
FROM thetable WHERE e_date =
DATE_ADD($your_date, INTERVAL 90 DAY)';

How to check given date period is between two dates in MySQL and PHP

I have a travel history of the employee. I want to check, for the particular month, whether he is in outstation (traveled outside) or in the office, to calculate number of hours in travel. Just we are maintaining the travel database, in that we entered employee name with client place traveled with travel date and returned date.
One employee have the following data:
Traveled date: '2015-08-29' (29th Aug 2015)
returned date: '2015-11-06' (6th Nov 2015)
So here, I want to check in the month of October, all employees that are out of the office. Obviously this guy should come in that category, but I could not get him.
I also tried directly in MySQL workbench, but I didn't get the result.
My original PHP code:
// $req['date_start'] = '2015-10-01'
// $req['date_end'] = '2015-10-31'
$employeeTravel = new EmployeeTravelRecord();
$TravelEntryList = $employeeTravel->Find("(travel_date between ? and ? or return_date between ? and ? )",array($req['date_start'], $req['date_end'],$req['date_start'], $req['date_end']));
$startdate = $req['date_start'];
$enddate = $req['date_end'];
foreach($TravelEntryList as $Travelentry){
$key = $Travelentry->employee;
if($startdate >= $Travelentry->travel_date)
{
$firstdate = $startdate;
}
else
$firstdate = $Travelentry->travel_date;
if($enddate <= $Travelentry->return_date )
{
$lastdate = $enddate;
}
else
$lastdate = $Travelentry->return_date;
$holidays = $this->getholidays($firstdate,$lastdate);
$totalhours = $this->getWorkingDays($firstdate,$lastdate,$holidays); //It returns in total time of outstation in hours excluding company holidays
$amount = $totalhours;
if(isset($TravelTimeArray[$key])){
$TravelTimeArray[$key] += $amount;
}else{
$TravelTimeArray[$key] = $amount;
}
}
But my input data doesn't retrieve that particular employee record, because both traveled date and returned date don't fall in my input dates.
MySQL Workbench:
SELECT * FROM employeetravelrecords where travel_date between '2015-10-01' and '2015-10-31' or return_date between '2015-10-01' and '2015-10-31';
I got only the following result:
+----+----------+---------------+----------------+----------+------------------+------------------+----------------+
| id | employee | type | project | place | travel date | return date | details |
+----+----------+---------------+----------------+----------+------------------+------------------+----------------+
| 13 | 38 | International | PVMTC Training | Hongkong | 11/10/2015 13:33 | 28/11/2015 13:33 | PVMTC Training |
| 14 | 48 | International | PVMT | VIETNAM | 10/10/2015 9:28 | 1/1/2016 9:28 | PETRO |
| 17 | 57 | International | PVMT | Saudi | 10/10/2015 11:39 | 2/1/2016 11:39 | |
+----+----------+---------------+----------------+----------+------------------+------------------+----------------+
The following record didn't get retrieved by this query:
+---+----+---------------+------+-----+-----------------+-----------------+-----------------+
| 7 | 22 | International | MOHO | XYZ | 29/8/2015 18:00 | 6/11/2015 18:00 | FOR DDS review |
+---+----+---------------+------+-----+-----------------+-----------------+-----------------+
SELECT * FROM employeetravelrecords
WHERE
return_date >= '2015-10-01' /* start parameter */
and travel_date <= '2015-10-31' /* end parameter */
The logic seems a little mind-bending at first and I've even reordered the comparisons a little from my original comment above. Think of it this way: you need to return after the start of the range and leave before the end of the range in order to have an overlap.
For a longer explanation and discussion you might find this page useful: TestIfDateRangesOverlap
SELECT '2015-08-29' < '2015-10-31' AND '2015-11-06' >= '2015-10-01' on_leave;
+----------+
| on_leave |
+----------+
| 1 |
+----------+
You can use between for get data between two dates. Here is the working example.
Here is my table structure :
Table User
user_id user_name created_date modified_date
1 lalji nakum 2016-01-28 17:07:06 2016-03-31 00:00:00
2 admin 2016-01-28 17:25:38 2016-02-29 00:00:00
And here is my mysql query :
Query
SELECT * FROM `user` WHERE created_date between '2015-12-01' and '2016-12-31' or modified_date between '2015-12-01' and '2016-12-31'
Result of above query :
Result
user_id user_name created_date modified_date
1 lalji nakum 2016-01-28 17:07:06 2016-03-31 00:00:00
2 admin 2016-01-28 17:25:38 2016-02-29 00:00:00
You want to find all those people who are not available for the complete duration say between T1 & T2 (and T2 > T1). The query you used will only give users whose start date and return date both lie between the given interval which is not the required output.
So to get the desired output you need to check for all employees who have started their journey on or before T1 and return date is on or after T2 (thus unavailable for complete interval [T1, T2]). So the query you can use is:
SELECT * FROM employeetravelrecords where travel_date <= '2015-10-01' and return_date >= '2015-10-31';
If you want employees who are even partially not available between the given duration then we need employees who started their travel before T1 and have any return date later than T1 (thus making them atleast unavailable for a part of the given interval):
SELECT * FROM employeetravelrecords where travel_date <= '2015-10-01' and return_date > '2015-10-01';

Validate a date range within MySQL query

(This question may seem easy or kind of noobish, by that I pardon my ignorance.)
I used PDO query to use SELECT then fetch some values, it comes to a point that I need to fetch only some entries that within its start date and end date.
My database
+----------+-----------------+----------------------+--------------------+
| id (INT) | title (VARCHAR) | start_date (VARCHAR) | end_date (VARCHAR) |
+----------+-----------------+----------------------+--------------------+
| 1 | buddy | 2012-11-26 | 2012-11-30 |
| 2 | metro | 2012-12-05 | 2012-12-20 |
| 3 | justin | 2012-11-28 | 2012-12-01 |
+----------+-----------------+----------------------+--------------------+
My query is as follows:
$query = "SELECT title, start_date, end_date FROM debts WHERE start_date >= CURDATE() AND end_date >= CURDATE()";
What I want to achieve is whenever the start_date is today or greater but not exceeding the end_date it will be valid. This will return the row for id 1, however if I change the start_date to 2012-11-25, it will fail due to the first condition on AND. I'm really confuse on this since I am new to this, is there any built-in function to handle this kind of situation?
This is better:
SELECT title, start_date, end_date FROM debts
WHERE date(now()) BETWEEN start_date AND end_date
SELECT title, start_date, end_date FROM debts
WHERE start_date >= CURDATE() AND end_date <= CURDATE()

Query: Calculate average price of stay depending on dates

Hello all,
I need to create a query for house search, that would match in database user entered data: date when they want to move in and leave, number of people they have in group and price per night.
Lets say user searched for house:
dates: from 2011-01-15 to 2011-03-01 (see on picture period A1C1), for 3 people, and he is willing to spend from $90 to $125 dollars per night.
This is my manual calculations for this search:
dates available in database
total number of dates user wants to stay is: 44 days
price for the first period 2011-01-15 to 2011-01-25 is 10 days * $100 = $1000
price for the second period 2011-01-25 to 2011-02-14 is 20 days * $120 = $2400
price for the third period 2011-02-14 to 2011-03-01 is 14 days * $140 = $1960
total average price per night = 1000 + 2400 + 1960 / 44 = $121.8
price and number of people matches user input, so we display this house
If you merge dates and calculate average price per night for the given period, search script should match array of data provided above.
My question is this: How my query should look like to calculate quickly if user data matches records in database.
I was thinking about using SQL DATEDIFF function and then multiply by price ... etc but it looks to me pretty complex.
I will appreciate any advice.
Thank you
UPDATE
Here is my database schema:
Table "apt_search_periods" which stores all merged dates (continuous dates from availability table)
+-----------+------------+------------+-----------+--------------+--------+
| period_id | start_date | end_date | rental_id | nb_of_people | merged |
+-----------+------------+------------+-----------+--------------+--------+
| 21 | 2011-03-31 | 2012-03-31 | 548 | 4 | y |
+-----------+------------+------------+-----------+--------------+--------+
Table "apt_search_periods_avail" linking merged dates with availability table
+----+-----------+-----------------+
| id | period_id | availability_id |
+----+-----------+-----------------+
| 21 | 21 | 20953 |
| 22 | 21 | 20952 |
| 23 | 21 | 4033 |
+----+-----------+-----------------+
Table "availability" with expanded dates and prices
+-------+-----------+------------+------------+--------------+--------------+
| id | rental_id | start_date | end_date | nb_of_people | rent_per_day |
+-------+-----------+------------+------------+--------------+--------------+
| 20952 | 548 | 2011-03-31 | 2011-07-01 | 4 | 575 |
| 4033 | 548 | 2011-07-01 | 2011-09-01 | 4 | 680 |
| 20953 | 548 | 2011-09-01 | 2012-03-31 | 4 | 575 |
+-------+-----------+------------+------------+--------------+--------------+
Following should get you started.
Note that the only difference is that the third period comprises 15 days io 14 according to DATEDIFF.
SQL Statement
;WITH q AS (
/* Kick of with the record where startdate < input < enddate */
SELECT date_start
, date_end
FROM #HouseSearch
WHERE date_start <= #date_start
AND date_end >= #date_start
AND nb_people >= #nb_people -- Only when number of people is adequate
UNION ALL
SELECT q.date_start
, hs.date_end
FROM q
INNER JOIN #HouseSearch hs ON hs.date_start = q.date_end
WHERE nb_people >= #nb_people -- Only when number of people is adequate
)
SELECT *
FROM (
-- Only return result if sequence exists between date range
SELECT date_start = MIN(date_start)
, date_end = MAX(date_end)
FROM q
WHERE date_end >= #date_end
) datetimerange
-- Calculate the average price
CROSS APPLY (
SELECT [AveragePrice] = SUM(price / DATEDIFF(dd, #date_start, #date_end))
FROM (
-- Price for all records where date_end <= #date_end
SELECT [price] =
CASE WHEN #date_start < date_start
THEN DATEDIFF(dd, date_start, date_end) * price
ELSE DATEDIFF(dd, #date_start, date_end) * price
END
FROM #HouseSearch
WHERE #date_end > date_end
UNION ALL
-- Price of remaining records where date_end >= #date_end
SELECT DATEDIFF(dd, date_start, #date_end) * price
FROM #HouseSearch
WHERE #date_end between date_start AND date_end
) prices
) price
WHERE date_start IS NOT NULL
Test data
DECLARE #HouseSearch TABLE (
date_start DATE
, date_end DATE
, nb_people INTEGER
, price FLOAT
)
INSERT INTO #HouseSearch VALUES
('2011-01-01', '2011-01-25', 4, 100)
, ('2011-01-25', '2011-02-14', 3, 120)
, ('2011-02-14', '2011-03-12', 3, 140)
, ('2011-03-12', '2011-04-10', 3, 100)
DECLARE #date_start DATE = '2011-01-15'
DECLARE #date_end DATE = '2011-03-01'
DECLARE #nb_people INTEGER = 3
DECLARE #price_low FLOAT = 90
DECLARE #price_high FLOAT = 15

Categories