calculate total number of days in specied dates - php

i have one table with two columns as shown in picture
table columns names are (MAXDATE,AMOUNT).
if you see we have
first date range (from current date to 20-jan-2010)
second date range from 20-jan-2010 to 30-jan-2010
3rd range is from 20-jan-2010 to 31-jan-2010.
at the execution of page user enter the start and end date.
for example, if user put
start date: 18-jan-2010
end date: 23-jan-2010
then he has 2 dates in first options and 3 dates in second options.
what i want to calculate in sql
1. how many days in first range (if any this depends on supplied dates from user)
2. how many days in 2nd range (if any this depends on supplied dates from user)
3. how many days in 3rd range (if any this depends on supplied dates from user)
Thanks

Here is an example how to calculate days.
http://dev.mysql.com/doc/refman/5.0/en/date-calculations.html

You can do all of this in MySQL:
SELECT DATEDIFF(NOW(), max_date) as days;
SELECT DATEDIFF(date2, date1) FROM
(SELECT max_date as date1 FROM table1 LIMIT 1) as s1
JOIN
(SELECT max_date as date2 FROM table1 LIMIT 1 OFFSET 1) as s2;
//etc.

Related

Finding ocuppations via SQL and/or PHP

I am making a student web app. Amongst other tables, I have a table in which students enroll and enrollments are between two dates.
This app uses MySQL 5.6 and PHP 7.2
It has the following fields:
IDStudent
StartDate
EndDate
IDCourse
Each course has a maximum capacity in which it cannot be surpassed.
I want to know, given a start date, end date and IDCourse, how many concurrent students are in a course. I get an approxiumate value just counting rows between two dates
SELECT COUNT(*) FROM enrollments
WHERE IDCourse = ?
AND (
(StartDate BETWEEN "<start date>" AND "<end date>")
OR
(EndDate BETWEEN "<start date>" AND "<end date>")
OR
(StartDate <= "<start date>" AND EndDate>= "<end date>")
)
But that doesn't take account non overlapping ranges. It counts every enrollment.
For example, I have this very simple case:
Want to find how many students are enrolled between 01/01/2021 and 05/01/2021 at a specified course
And I have those 3 enrollments on that course:
01/01/2021 - 02/01/2021
03/01/2021 - 04/01/2021
20/12/2020 - 01/02/2021
I should get 2 count and not 3, because 1 and 2 don't overlap while 3 overlaps both.
I tried to search online but I didn't found something similar, maybe I am not using the correct keywords!
I found Determine max number of overlapping DATETIME ranges but that is for MySQL 8
Many thanks for your help
Regards
I think you may need to create a calendar table between the first start date and the last end date, count by date and then select the max between the period you are interested:
select max(stcount)
from
(
select c.dt, count(*) stcount from calendar_table c
join enrollments e on c.dt between e.StartDate and e.EndDate
group by c.dt
) countbydate
where dt between '2021-01-01' and '2021-01-05'
db-fiddle:
https://www.db-fiddle.com/f/dXuKMoRQ2ivLt5qi5AVFcG/0

Mysql find dates using where in clause, or dates nearest to those in array

I have the following code and query:
//$month is an array of datetime objects
foreach($month as $key => $indMonth){
$formattedMonth[] = $month[$key]->format('Y-m-d');
}
$formattedMonths = implode("','",$formattedMonth);
$query = "SELECT id,date FROM table WHERE date in ('$formattedMonths') ORDER by date DESC";
The database holds dates for the past 450 days, but it is imperfect and there are some missing days. The point of the script is to retrieve data from the current day of the month and then the corresponding day on the five previous months, but I need a failsafe for when a date happens to be missing.
How can I modify this query so it picks either the date in the "where in" portion of the query or it finds the date nearest to that particular date in the array?
Is this best to do in the query, or am I better off returning a more complete data set, then using PHP to find out if the date I want is available?
MySQL offers some decent date arithmetic. For example, if you have the date '2015-11-10' (10-Nov-2015) you can get the same day three months prior with this expression:
'2015-11-10` - INTERVAL 3 MONTH
That will kick back '2015-08-10', which is what you want.
This date arithmetic works predictably even with longer and shorter months, and with leap years. For example,
'2015-03-31' - INTERVAL 1 MONTH, '2016-03-31' - INTERVAL 1 MONTH
gives back '2015-02-28', '2016-02-29' as you might expect. And
'2015-03-31' - INTERVAL 2 MONTH, '2016-03-31' - INTERVAL 2 MONTH
gives back '2015-03-31', '2016-03-31'. Perfect.
Now, only you can decide whether this predictable behavior is correct for your application: only you know what you want to do with the previous five months of data, when the day in question is near the end of the month.
Let's assume it's correct and move on. Here is a subquery that can be used to generate a sequence of six dates, one day per month ending today.
SELECT CURDATE() - INTERVAL seq.seq MONTH day_of_month
FROM ( SELECT 0 AS seq UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL
SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 6) seq
We can use this little query as a subquery, and LEFT JOIN it to your data. That would work like this:
SELECT id, day_of_month
FROM (
SELECT CURDATE() - INTERVAL seq.seq MONTH day_of_month
FROM ( SELECT 0 AS seq UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL
SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 6) seq
) days
LEFT JOIN table ON table.date = days.day_of_month
This is a cool way to do it because you'll always get at least one row in the resultset for each date in the list, even if there's nothing matching in table.
The closest date gets a little hairier. It's possible to write a query like that. But MySQL lacks a WITH clause so the query is ridiculously repetitive.

Select continues dates from table

This is little confusing me how to select dates from table on continuous basis.
Suppose i have absent_report table and have entries like this,
Sno Code date
1 101 01-01-2014
2 101 02-01-2014
3 101 03-01-2014
4 101 05-01-2014
5 101 06-01-2014
6 101 07-01-2014
I only want to select continues date from a date. like first three dates not fourth one and so on.
Example Like I have date from which I have to compare is Like 31-12-2013 now from here next continues dates like 01-01-2014,02-01-2014,03-01-2014 only, No matter next records like i have dates in that table 05-01-2014,06-01-2014,07-01-2014. I just want first continuous dates.Hope this clear more what I want.
Use the BETWEEN syntax
SELECT * FROM table WHERE date BETWEEN '2014-01-01' AND '2014-01-03';
You can check if either the next row has the following day or the previous row has the previous day. To do this, I used DATE_ADD() as described in this answer. However, I am not sure if this would be better than implementing the logic in PHP alltogether.
SELECT sno, code, date FROM table AS current
WHERE
DATE(DATE_ADD(date, INTERVAL -1 DAY)) = (SELECT date FROM table AS previous WHERE previous.date < current.date ORDER BY date DESC LIMIT 1)
OR
DATE(DATE_ADD(date, INTERVAL +1 DAY)) = (SELECT date FROM table AS next WHERE next.date > current.date ORDER BY date ASC LIMIT 1)
ORDER BY date ASC
See it work here.

calculate amount on dates difference

i have one table with two columns as shown in picture
at the execution of page user enter the start and end date.
now what i need to calculate is total amount.
for example, if user put
start date: 18-jan-2010
end date: 23-jan-2010
then he has 2 dates in first options (20$) and 3 dates in second options (26$) so total will be (56$).
first i want to calculate in sql
1. how many days in first range (if any this depends on supplied dates from user)
2. how many days in 2nd range (if any this depends on supplied dates from user)
3. how many days in 3rd range (if any this depends on supplied dates from user)
then
we will multiply days with Amount in php for each range.
at the end i want to get grand total also in php.
Maybe:
SELECT SUM(amount) FROM your_table WHERE date BETWEEN start_date AND end_date GROUP BY user
SELECT 'In Range' AS SumType
SUM(amount)
FROM <table>
WHERE date BETWEEN start_date AND end_date
UNION
SELECT 'Outside Range' AS SumType
SUM(amount)
FROM <table>
WHERE date < start_date OR date > end_date
UNION
SELECT 'Grand Total' AS SumType
SUM(amount)
FROM <table>

Mysql BETWEEN clause being ignored. No syntax error

im trying to show items booked between two separate date columns (start and end dates). i want to search between the dates but the query seems to ignore any dates that land between the selected dates.
SELECT
bookings.booking_id,
bookings.booking_id,
bookings.booked_from,
bookings.booked_from,
bookings.booked_till,
item_set_computer.item_id,
item_set_computer.name,
item_set_computer.booking_groups_id
FROM
bookings,
item_set_computer
WHERE
item_set_computer.item_id = bookings.item_id
AND
item_set_computer.booking_groups_id = 3
AND
booked_from
BETWEEN "2010-04-13" AND "2010-04-20"
AND
booked_till
BETWEEN "2010-04-13" AND "2010-04-20"
for instance, I have an item booked from 13th to 15th. date1 is 2010-04-13 and date2 is 2010-04-15. User searches for booked items from 14th to 16th. It returns no results. Why is it ignoring database dates that drop between dates selected by the user? The columns are set as DATE in the database and have been correctly entered.
You said "User searches for booked items from 14th to 16th."
That means your query will be
AND
booked_from
BETWEEN "2010-04-14" AND "2010-04-16"
AND
booked_till
BETWEEN "2010-04-14" AND "2010-04-16"
The first AND clause will obviously be false (since your 4/13 start date is NOT indeed between 4/14 and 4/16)
The correct logic for you (assuming you want the FULL booking interval) is
AND booked_from >= "2010-04-14"
AND booked_till <= "2010-04-16"
Or if you want partial interval
AND booked_from >= "2010-04-16" -- means we booked before the end of interval
AND booked_till <= "2010-04-14" -- means we left after the start
are there recordsets with the same id in both table which falls under the clause? also make sure that with WHERE col BETWEEN a AND b, a has to be smaller than b to work.
what gets returned if you comment out the last 6 lines?

Categories