How to get active rent's details for given month - mysql

I want to get active rent's for given month. I have a table where i have rent details. In that table i have start date, end date and how many months. So when i select a month i want to know what are the rents currently active using mysql
Example
House A 1.1.2019 31.12.2019 12
House B 1.2.2019 31.05.2019 03
House C 1.4.2019 31.12.2019 08
If i select month June result should be House A and House C, and if i select march result should be All three (A, B, C)
Can someone help me with mysql query?

This is the overlapping range problem, where the first range is the range of rents dates, and the second range is the span of a certain month. For June, 2019, we can try:
SELECT *
FROM yourTable
WHERE rent_end >= '2019-06-01' AND rent_start <= '2019-06-30';
Demo

Related

MySQL - Day, Month, Unspecified Year

I'm working with 4 tables as following:
hotels(hotel_num, hotel_name, city)
rooms(room_num, hotel_num, room_type, price)
bookings(hotel_num, guest_num, arr_date, dep_date, room_num)
guests(guest_num, guest_name, guest_address)
I have to find bookings where someone will be staying at a particular hotel on New Year's Day but of a non specific year.
I have tried:
(SELECT COUNT(*)
FROM hotels AS h
JOIN rooms AS r
JOIN bookings AS b
ON h.hotel_num = r.hotel_num
AND b.hotel_num = h.hotel_num
AND b.room_num = r.room_num
WHERE h.hotel_name = 'Hotel California'
AND 01 BETWEEN MONTH(b.arr_date) AND MONTH(b.dep_date)
AND 01 BETWEEN DAY(b.arr_date) AND DAY(b.dep_date)
GROUP BY b.hotel_num);
I imagine this approach isn't working from the point of view that a booking can start on Christmas Day and end in February but the month goes from 12 to 2 which 1 is not between.
Is there a way to specify a month and day without a year?
Edit: Results should be a number, ie 7, which tells you how many rooms are booked on 01/01/xxxx
I think this condition will select the bookings on "New Years Day":
where year(arr_date)<>year(dep_date)
Unless someone arriving on "New Years "day" and departing on the same day should also be selected, but that is not very hard to add, is it?

adding row value to total if condition (don't know how to ask this)

I'm running a points system for companies where every employee that works for that company is worth some points.
Every month the points for the companies are calculated.
This works so far, however In the 9th month of this year I would like to give double points for each acquired employee in that month.
I don't know how to do that.
I have this query now:
SELECT company, (employees *2) as "Points"
FROM data
WHERE month = '10'
GROUP BY company
But as you can see I give 2 points for each employee that works for that company in that month.
But for month 9 I want to give double points and add them to current points in current month(10)
I have this SQLfiddle as example: http://sqlfiddle.com/#!9/2cb812/7
Expected result:
company Points
__________________
company 1 26 + (extra points from month 9)
company 2 32 + (extra points from month 9)
company 3 44 + (extra points from month 9)
So it's all about the August/September delta 2018. If you run the query for any month before September 2018 (June 2018, May 2012, whatever), you just want to get the current month's points. If you run the query for any month after August 2018 (December 2018, March 2022, ...) you want the 2018 bonus points added.
Group by company and use conditional aggregation (an aggregation function on a condition) in order to calculate this.
We must look at the requested month (e.g. 10/2018) and August 2018 and September 2018.
SET #yearmonth = '201810';
SELECT
company,
SUM(
CASE WHEN yearmonth = #yearmonth THEN employees * 2 ELSE 0 END +
CASE WHEN #yearmonth >= '201809' AND yearmonth = '201809' THEN employees * 4 ELSE 0 END -
CASE WHEN #yearmonth >= '201809' AND yearmonth = '201808' THEN employees * 4 ELSE 0 END
) AS points
FROM data
WHERE yearmonth in ('201808', '201809', #yearmonth)
GROUP BY company
ORDER BY company;
The WHERE clause is superfluous, as the months are checked inside the SUM function, but it may speed up the query.
Rextester demo: https://rextester.com/ELOWTL44361

Need help for join and some calculations on a MySql insert

I'll try to provide some context so you can understand what I'm trying to achieve here. My company uses open source software to manage the employees leaves (Jorani, feel free to google it :) ).
There are different types of leave (holidays, sick leave, etc.) and we want to calculate the days "not used" from the holidays of 2016 and "copy" them to another type of leave called "Remaining Holidays 2016".
The important tables are:
entitleddays (here you specify how many days of each type you give to an employee)
id employee startdate enddate type days description
661 3 2016-01-01 2017-02-28 1 14.00 Holidays 2016
1296 3 2016-01-01 2016-12-31 4 18.00 Sick leave 2016
leaves (this table has information about the leaves taken by the employees)
id startdate enddate status employee cause duration type
2436 2016-08-01 2016-08-01 3 78 OK from managers 1.00 1
2766 2016-09-05 2016-09-12 3 63 Holidays 6.00 1
So basically we have:
Entitled leaves:
Data stored in the entitleddays table shown above. In our example let's say I have 14 days for my 2016 holidays.
Taken leaves:
Leaves taken by the user, stored in the table called leaves shown above. For our example let's say I took a day off the first of August and 6 days on September.
Available leaves:
Available days are calculated: entitled days minus "taken leaves". For this examplee, 14 entitled days - 7 = 7 days. So I still have seven days available for holidays :D
So my goal is to insert these 7 days for this user as entitled days for the new type: "Remaining days from 2016" and do this for every user. So the solution that comes up to my mind is to do something like this for every user:
INSERT INTO entitleddays (employee, startdate, enddate, type, days, description)
SELECT id, '2017-01-01', '2017-02-31', '8', (entitled holidays for 2016 minus all the taken leaves of this type), 'Remaining holidays from 2016'
FROM users
Where 8 is the new type of leave where I want to copy the days (Remaining holidays from 2016).
For example I can get the taken holidays from 2016 for a specific user doing this:
SELECT SUM(duration)
FROM leaves
WHERE employee=3 AND status=3 AND type=1
Note: Type 1 is the type of leave "Holidays 2016" and status 3 means that the leave request was accepted.
I can probably achieve all of this in a single SQL instruction but it can also be split in more if simpler or easiest to manage/understand.
Many thanks in advance.
This is how you can handle the calculation:
sum the entitleddays in a subquery by grouping the datasets in its table per employee
maybe even group by year? In this case I just filtered for 2016 via WHERE-clause
sum the taken holidays in a subquery, again by grouping per employee
group by year or filter directly for the one you need
join this subquery onto the other resultset of the other query
calculate (entitled days - taken leaves) in the outer query
Query:
SELECT
entitled.employee,
'2017-01-01',
'2017-02-31',
'8' AS type,
entitled.days - takenDays.days,
'Remaining holidays from 2016'
FROM
(
SELECT
employee,
SUM(days) AS days
FROM
entitleddays
WHERE
startdate >= '2016-01-01'
AND type = 1
GROUP BY
employee
) AS entitled
LEFT JOIN (
SELECT
employee,
SUM(duration) AS days
FROM
`leaves`
WHERE
startdate >= '2016-01-01'
AND type = 1
GROUP BY
employee
) AS takenDays ON takenDays.employee = entitled.employee
I am not sure if this is how you want to calculate the sums for the days of entitleddays and taken days. The query just checks if startdate >= '2016-01-01'.
Also you mentioned a table users in your attempt but didn't provide details for the table, so I left it out. I guess you could use it as a basis otherwise. In the current query the grouped result of entitleddays is the basis.
For the insert
INSERT INTO entitleddays (employee, startdate, enddate, type, days, description)
SELECT
entitled.employee,
'2017-01-01',
'2017-02-31',
'8' AS type,
entitled.days - takenDays.days,
'Remaining holidays from 2016'
FROM
(
SELECT
employee,
SUM(days) AS days
FROM
entitleddays
WHERE
startdate >= '2016-01-01'
AND type = 1
GROUP BY
employee
) AS entitled
LEFT JOIN (
SELECT
employee,
SUM(duration) AS days
FROM
`leaves`
WHERE
startdate >= '2016-01-01'
AND type = 1
GROUP BY
employee
) AS takenDays ON takenDays.employee = entitled.employee

Grouping months by quarter over multiple years depending on a dynamic start month

Using MySQL and PHP I am building a JSON array to populate a data table.
For the purposed of my question suppose the data table has the following columns:
Year: 2010,2011,2012,2013...<br/>
Month: 1,2,3,4,5...<br/>
Value: 100, 150, 200 etc...<br/>
The table structure cannot be altered and my solution needs come into the MySQL query
The data can be viewed either monthly, quarterly or yearly. Monthly and yearly is achieved easily through grouping by year and month.
Quarterly data can be grouped by calendar quarter (Jan-Mar, Apr-Jun, Jul-Sep, Oct-Dec) by this group statement:
GROUP BY year, round((month/3)+0.3,0)
So where Jan, Feb and March might all have 100 for their value the summed result is 300, same for other months.
Now my problem comes when I want to group values by a financial quarter, for example a quarter that starts in Feb, or any other quarters.
I have a statement that works for the quarter grouping using two variables that can be accessed via the SQL query, start_year (i.e. 2014) and start_month (i.e. 2)
GROUP BY year, (((round(((((month-(start_month-1))+((year-start_year)*12))-((year-start_year)*12))/3)+0.33,0)/4)+4)-floor(((round(((((month-(start_month, '%m')-1))+((year-start_year)*12))-((year-start_year*12))/3)+0.33,0)/4)+4)))*12
which basically will assign a 0,3,6,9 value to each calendar month for the purposes of grouping.
In the financial year starting February this works fine for quarters 1-3, however breaks for the final quarter as it includes Nov and Dec 2014 data and Jan from 2015.
As a result I get 5 rows of data instead of 4.
This is because of the preceding GROUP by year clause, an important addition as we might want to generate a table that views sequential quarters for multiple years.
So what I am looking for is a way of grouping the years together by offsetting the start month.
So when the year starts in Jan it will group Jan-Dec but if we change that to starting Feb it will group Feb-Jan.
Any ideas, suggestions most welcome!
Regards,
Carl
I solved a similar problem just now (a Moodle report aggregating assignment scores by year and quarter) with something like this:
select year(from_unixtime(s.timemarked)) as year, quarter(from_unixtime(s.timemarked)) % 4 + 1 as quarter, count(distinct data1) as "tickets graded" from mdlassignment_submissions s where grade >= 0 group by year, quarter order by year, quarter;
The relevant part for what you're doing is quarter(from_unixtime(s.timemarked)) % 4 + 1 as quarter
As another commenter pointed out, MySQL has a quarter() function, but it doesn't do financial quarters. However, since (as I understand it, at least, based on consulting the relevant wikipedia page) financial quarters are just offset by 1, the % 4 + 1 at the end should convert it.

Date ranking in Access SQL?

I have a query pulling the last six months of data from a table which has a column, UseDates (so as of today in June, this table has dates for December 2011 through May 2012).
I wish to include a "rank" column that associates a 1 to all December dates, 2 to all January dates, etc -- up to 6 for the dates corresponding one month prior. If I were to open up this query a month from now, the 1 would then be associated with January, etc.
I hope this makes sense!
Example, if I ran the query right now
UseDate Rank
12/31/2011 1
1/12/2012 2
...
5/23/2012 6
Example, if I ran the query in August:
UseDate Rank
2/16/2012 1
3/17/2012 2
...
7/21/2012 6
Example, if I ran the query in March:
UseDate Rank
9/16/2011 1
10/17/2011 2
...
2/24/2012 6
SELECT
UseDates,
DateDiff("m", Date(), UseDates) + 7 AS [Rank]
FROM YourTable;
You can use month function for UseDates and subtract it from the result of now function. If it goes negative, just add 12. Also you may want to add 1 since you start with 1 and not 0. Apparently it should work for half a year date ranges. You'll get into trouble when you need to "rank" several years.
You can rank with a count.
SELECT
Table.ADate,
(SELECT Count(ADate)
FROM Table b
WHERE b.ADate<=Table.ADate) AS Expr1
FROM Table3;
You have to repeat any where statement in the subquery:
SELECT
Table.ADate,
(SELECT Count(ADate)
FROM Table b
WHERE b.ADate<=Table.ADate And Adate>#2012/02/01#) AS Expr1
FROM Table3
WHERE Adate>#2012/02/01#