get the scheduling data based on 3 years in mysql - mysql

I have one table bibles that having two columns only i.e. is below:-
id chapter_name
1 Mathews 1
2 Mathews 2
3 Mathews 3
4 Mathews 4
... ....
... ....
364 Revelation 22 //Total Records only 364 fixed. that will not increase
Bible Scheduling starts from 5 sept 2021 for 3 years and ends on 31 Aug 2024 i.e basically bible repeats three time in 3 years.
Now Suppose today date is 8 Sept 2021
id chapter_name date_1 date_2 date_3
1 Mathews 1 2021-09-05 2022-09-04 2023-09-03
2 Mathews 2 2021-09-06 2022-09-05 2023-09-04
3 Mathews 3 2021-09-07 2022-09-06 2023-09-05
4 Mathews 4 2021-09-08 2022-09-07 2023-09-06
... ....
... ....
So now requested date is 8 spet 2021 i want to fetch the 4th record Mathews 4 and now suppose today date is 6 sept 2022 and now want to fetch the 3 row Mathews 3.
Note : these date columns are not stored in database. i have only two columns id, chapter_name.. Reason for not storing the dates because after three years i need to update again that dates to make scheduling works. Is there any way to fetch the rows?
Below answer works fine but I have two types of Bibles that starts from Id 1 to 364 another starts from 365 to 1456... 1st case
1 to 364 works.. but 365 to 1456 not works

If I understand correctly, then logic you want is:
where dateadiff(?, '2021-09-05') % 364 = id - 1
The ? is a parameter for the date you pass in.

You can start with some anchor date in the past, 2020-09-06 will do.
The id in your table is a number of days between the anchor date and the current date mod 364 (the number of rows in your table).
SELECT
id, chapter_name
FROM bibles
WHERE
id = DATEDIFF(CURRENT_DATE(), '2020-09-06') % 364 + 1
;
The DATEDIFF(CURRENT_DATE(), '2020-09-06') function returns the number of days between the current date and the anchor date 2020-09-06, i.e. the number of days between the date when the schedule started and now. This number can grow larger than 364 (the number of rows in your table). To "wrap" this number back to 0 when it is larger than 364 we use the modulo division (mod) or % operator. And then add 1, because ids in your table start with 1 (if they started with 0 you didn't have to add 1).
Try to run this query replacing the CURRENT_DATE() with your sample dates 2021-09-08 and 2022-09-06.
SELECT DATEDIFF('2021-09-08', '2020-09-06') % 364 + 1;
returns 4 (4th row)
SELECT DATEDIFF('2022-09-06', '2020-09-06') % 364 + 1;
returns 3 (3rd row)
It means that if you run the full query with the CURRENT_DATE() function on 2021-09-08 it will return a row with id=4. When you run the query on 2022-09-06 it will return a row with id=3.

Related

Matching days of week for a given date range

I am working on a space booking system and is trying to find out if the space is available for a given date range. So I have 2 tables -
space_master
id space_address start_time end_time
space_availability
space_id days_of_week
Note -
(a) start_time and end_time are DATETIME fields in MYSQL
(b) days_of_week are numbers where Sunday is represented by 1 and so on
(c) one space can be available on multiple days (example follows)
space_master
id space_address start_time end_time
1 Florida 2012-03-18 10:21:00 2012-03-29 4:21:00
2 London 2012-04-21 09:00:00 2012-06-18 10:00:00
space_availability
space_id days_of_week
1 1
1 2
2 4
2 5
2 6
This means the first space (with id 1) is available between 2012-03-18 10:21:00 and 2012-03-29 4:21:00 but only on Sunday and Monday. Now I am trying to write a function that will take booking_start_time and booking_end_time (all DATETIME in MYSQL) as input then scan the available spaces table and return the availble bookings. Something like this -
getBooking(2012-03-19 10:21:00, 2012-03-19 15:21:00) - returns the space with id 1 (as 19th March 2012 was a Monday and hence available)
getBooking(2012-03-19 10:21:00, 2012-03-20 15:21:00) - returns nothing since 20th March is a Tuesday on which the space is not available.
Any idea how to do this? I was first trying to do this in a single query. But is that even possible?
EDIT: the sqlfiddle link follows -
http://sqlfiddle.com/#!9/8a6e1a

Sort values in two column and insert order position into another column in mysql

I have a database about sports event that contains:
*User ID
*Amount of Points that the user got on that event
*Time (HH:MM:SS) that took the user to complete track.
How can I first sort them by no. of points, then if two users have same amount of points, by time (shorter is better); and then insert the places to rows?
I have database like that:
ID No. of Points Time Place
------------------------------------
1 15 00:56:00
2 13 00:55:15
3 17 01:00:00
4 17 00:57:00
5 19 00:52:15
I need to have it with places:
ID No. of Points Time Place
------------------------------------
1 15 00:56:00 4
2 13 00:55:15 5
3 17 01:00:00 3
4 17 00:57:00 2
5 19 00:52:15 1
I hope, you understand that. Sorry for bad English.
Best regards,
You can do this with update statement as follows.
SET #placeValue:=0;
UPDATE [Table Name] SET Place=#placeValue:=#placeValue+1 ORDER BY
[Amount of Points] DESC,Time ASC

Selecting partial data for day based on when column value meets condition

I am using Access 2010. My SQL knowledge is limited and I haven't been able to figure out how to code the following rules.
I have a datetime column that I sort by datetime and then group by date (using group by int(datetime).
Now I want to select records within each date up to and including the point a condition is met. Once condition is met, then that record with all preceding records will be returned as the record set for that day. Records for that date following a matching condition will be ignored.
My data has:
Trade DateTime Points CumPoints
1 11/20/2015 9:31 AM 2 2
2 11/20/2015 9:49 AM 1 3
3 11/20/2015 9:55 AM 1.25 4.25
4 11/20/2015 10:20 AM -1.5 2.75 -- record ignored
5 11/20/2015 10:21 AM -0.75 2 -- record ignored
6 11/20/2015 10:36 AM 5.25 7.25 -- record ignored
1 11/23/2015 9:30 AM 2 2
2 11/23/2015 10:07 AM -1.25 0.75
3 11/23/2015 10:29 AM 0.5 1.25
4 11/23/2015 11:07 AM -1.25 0
5 11/23/2015 11:23 AM -0.25 -0.25 -- record ignored
6 11/23/2015 12:53 PM -1 -1.25 -- record ignored
So if my rules are that once Cum-points >=4 or if Cum-points <= 0 after 11:00 AM then those records are returned. In the above example the query should return the first 3 records for the first date and the first 4 records for the 2nd date.
Any assistance will be appreciated.
That could be like this:
Select
DateValue([DateTime]) As [Date], Points, CumPoints
From
YourTable
Having
(CumPoints >= 4)
Or
(TimeValue([DateTime]) > #11:00:00 AM#
And
CumPoints <= 0)
Group By
DateValue([DateTime]) As [Date], Points, CumPoints
You will have to adjust as your sample data don't correlate with your description of the conditions.

Selecting id with difference betwen dates in same row being less than 30 days, but without new date in different row

I have a table like this
id plan_id cancel_date paid_date
9 2 2015-08-05 2014-09-13
10 2 2015-09-08 2015-09-03
10 3 NULL 2015-09-10
11 3 NULL 2015-09-13
14 3 2015-09-28 2015-09-14
And I would like to select ids where there is a less than 30 days difference between cancel_date and paid_date (for a given plan), and they didn't acquired a new plan in less than 30 days.
In this case, this would mean returning id 14 only.
Update:
Whenever a user buy a new plan, we insert it to the table, with a different paid_date (paid_date is the date that the plan was acquired the first time).

Aggregate values based on a date interval

I have a database containing monthly precipitation values at some measurements locations. The structure of my table is:
describe pp_lunare;
Field Type Null
ID int(11) NO
DATA_OBS date NO
PLUTON float NO
LEGHIN float NO
DUMBRAVA float NO
A sample of my data:
ID DATA_OBS PLUTON LEGHIN DUMBRAVA
1 1977-01-01 14.4 33.3 25.1
2 1977-02-01 18.7 12.9 13.2
3 1977-03-01 32.8 26.7 18.3
4 1977-04-01 109.6 123.8 140.6
5 1977-05-01 98.5 104.7 59.9
6 1977-06-01 192.9 172.8 66.6
7 1977-07-01 101.4 85.8 79.4
8 1977-08-01 116.4 103.3 105.7
9 1977-09-01 54.5 47.4 51.8
10 1977-10-01 23.6 15.6 11
11 1977-11-01 59.7 44.3 29.7
12 1977-12-01 28.7 13.1 10
In my case I need to get the sum of the precipitation for every column at every 3 months something like this:
ID DATA_OBS PLUTON LEGHIN DUMBRAVA
1 1977-03-01 65.9 72.9 56.6
2 1977-06-01 401 401.3 267.1
3 1977-09-01 272.3 236.5 247.9
and so on...
Thanks.
You can get the month from your date with month(data_obs) which returns a month from 1 to 12. Convert this to a value for the quarter by doing something like floor((month(data_obs) - 1)/3) as quarter to get quarters from 0 to 3.
For example, select data_obs, concat(year(data_obs), floor((month(data_obs) - 1)/3)) as quarter from pp_lunare; should show you both the original date and the derived quarter side by side.
Then group by this new value and sum the rest:
select concat(year(data_obs), floor((month(data_obs) - 1)/3)) as quarter, sum(pluton), sum(leghin), sum(dumbrava)
from pp_lunare
group by quarter
order by quarter;
If you want the exact date format you had in the question, you'll have to do a little bit of string manipulation (add 1 to the quarter above, multiply that by 3, pad with 0s, then tack on a "-01" for the date).
You can get the month data at first, and convert it into [quarter], which is from 0 to 2.
Then you can create three temporary tables given [quarter]=0,1,2,
and the easy and final part will be to add up the i_th row in these tables, the result will be just like below. And you can also have the data_obs data as well.
ID DATA_OBS PLUTON LEGHIN DUMBRAVA
1 1977-03-01 65.9 72.9 56.6
2 1977-06-01 401 401.3 267.1
3 1977-09-01 272.3 236.5 247.9