Find vacancy (no contract) days in each month for property/unit per year - sql

I need to get number of vacant days in each month in every year
Leasing Contracts
So, my target is to occupy all units along the year.
For that I have to find how many days in each month units are not occupied (There s not contract) and focus on these units to reduce the price or give promotions.
So, I have lease start and lease expiry dates for the units in the first table and I want to know in summary table (second table) number of days in each month which are not belong to any of the leasing period (from/to range) from the first table for each unit.
I need Excel formulas and/or SQL scripts to be applied to find all days without rent for each project/unit in the selected year
Appreciate your support in advance!
Project Name Unit No Lease Start Lease Expiry Rent Per Annum
Building1 Unit1 01-01-2017 31-12-2017 70000
Building1 Unit1 01-01-2018 15-08-2018 60000
Building1 Unit1 01-10-2018 31-12-2018 60000
Building1 Unit2 01-01-2017 31-12-2017 60000
Building1 Unit2 01-03-2018 31-07-2018 60000
Building1 Unit2 01-09-2018 30-09-2018 45000
Vacancies Days multiply by last daily rate renting (rent per annum)/365
Project Name Unit No Jan-18 Feb-18 Aug-18 Sep-18 Oct-18
Building1 Unit1 0 0 16*164 30*164 0
Building1 Unit2 31*164 28*164 31*164 0 31*123

I would use a calendar table.
This you join with your lease table to get whether a particular day is leased or not.
Then you can group by unit and month and do a pivot to get the result you want.

Related

SQL Query - Identifying entries between payment dates greater than 6 years

I have this table (in reality it has more fields but for simplicity, it will demonstrate what I'm after)
Payment_Type
Person ID
Payment_date
Payment_Amount
Normal
1
2015-01-01
£1.00
Normal
1
2017-01-01
£2.00
Reversal
1
2022-01-09
£3.00
Normal
2
2016-12-29
£3.00
Reversal
2
2022-01-02
£4.00
I need 2 specific things from this:
I need all entries where there is over 6 years difference between any given payment dates (when its been greater than or equal to 6 years from the date of the latest payment date). I don't need to count them, I just need it to return all the entries that meet this criteria.
I also need it to specify where a normal payment hasn't been made for 6 years or more from todays date but a reversal has however occurred within the last 6 years. (This might need to be a separate query but will take suggestions)
I'm using Data Lake (Hue).
Thank you.
I've tried to run a sub query with join and union but I'm not getting the desired results so will need to start from scratch. Any advice/insight on this is greatly appreciated.
Ideally, query one will show:
Payment_Type
Person ID
Payment_date
Payment_Amount
Normal
1
2015-01-01
£1.00
Normal
1
2017-01-01
£2.00
Normal
2
2016-12-29
£3.00
Query 2 results should show:
Payment_Type
Person ID
Payment_date
Payment_Amount
Normal
1
2017-01-01
£2.00
Reversal
1
2022-01-09
£3.00
Normal
2
2016-12-29
£3.00
Reversal
2
2022-01-02
£4.00

Pacing Period To Date Calculated Measure on SSAS cube - MDX

I want to produce a calculated member on our cube using MDX Expression that shows
revenue booked at any point in time up for the current date of a given
Measure
[Measures].[Rev]
Date Dimension
[Date].[Year]
Contract Dimension
[Contract].[Booking Date]
Year-Month
Rev
Pacing Rev
2021-01
10,000
10,000
2021-02
6,000
6,000
2021-03
12,000
12,000
2021-04
7,000
7,000
2021-05
9,000
4,500
2021-06
11,000
3,600
2021-07
13,000
1,000
Essentially I want to be able to determine how much Revenue was booked this time last year.
if today = 17/05/2022
I want to see Pacing Rev for all contracts booked for 2021 from any point in time up until today 17/05/22.
What I mean by 'from any point in time. i.e. a contract could have been booked in 2018, for 2021 (hence why I think I'll need to use the [Contract].[Booking Date] some how

Calculate total manufacturing output over a shift for each location

We currently have a master table stored in our SQL server with the following example information:
Site
Shift Num
Start Time
End Time
Daily Target
A
1
8:00AM
4:00PM
10000
B
1
7:00AM
3:00PM
12000
B
2
4:00PM
2:00AM
7000
C
1
6:00AM
2:00PM
5000
As you can see, there are multiples sites each with their own respective shift start & end times as well as a total daily target for the day.
Another table in the DB is populated by users via the use of a PowerApp. This PowerApp will push output values to the server like so:
Site
Shift Number
Output
Timestamp
A
1
2500
3/15/2022 9:45 AM
A
1
4200
3/15/2022 11:15 AM
A
1
5600
3/15/2022 12:37 PM
A
1
7500
3/15/2022 2:15 PM
This table contains a log of all time-stamped output entries for each site / shift.
What I would like to do is do a daily trend of output vs. target. In order to do so, all output values over a specific shift would have to be aggregated in a SUM function for a given shift grouped by the shift day. The resulting view would need to look like this:
Site
Shift Number
Day
Actual
Target
A
1
3/14
9500
10000
B
1
3/14
13000
12000
A
1
3/15
8000
10000
B
1
3/15
10000
12000
This is easy enough for daytime shifts (group by day and sum the output values). However, if you notice in the master table, Site B / Shift 2 crosses midnight. In this example, I would need to sum values from the previous day 4PM up until 2AM of today. The date grouping would be done by the Shift End Time. Here's an example of the problem area:
Site
Shift Number
Output
Timestamp
B
2
3300
3/15/2022 5:45 PM
B
2
2200
3/15/2022 8:15 PM
B
2
1600
3/16/2022 12:37 AM
B
2
2500
3/16/2022 1:15 AM
I would need these four rows to be aggregated in the view as one row like so:
Site
Shift Number
Day
Actual
Target
B
2
3/16
9600
10000
The values should be listed under March 16th since the end time of the shift occurs then. The values are summated and the target is taken from the daily target master table.
How can I properly calculate these outputs for each shift every day irrespective if it crosses into a new day or not in a view? Or should I go a different route altogether?

Select the rows of the group based on 2 conditions but combine the unique categories of that group

I have a table like below
ID Date Category Cycles
--------------------------------------------
RYI19 6/12/2018 TEMPERATURE 1567 y
RYI19 6/13/2018 VOLUME 1620 n
RYI19 6/25/2018 AREA 1890 y
RYI19 6/28/2018 TEMPERATURE 1435 y
TYI23 5/10/2020 LENGTH 1567 Y
TYI23 6/12/2020 LENGTH 1678 Y
TYI23 6/13/2020 LENGTH 1689 n
Before my only condition was to select first from the group
So I wrote this code:
select
ID, date
from
(select
ID, date,
row_number() over(partition by ID order by date) rn
from
table1) t1
where
rn = 1
Now I have 2 additional columns and 2 conditions if the group is within 2 days and cycles less than 100, don't consider that record. Ideally the cycles need to increase as date increases but in case it is smaller then only date condition of 2 days need to be considered for records to select or not. as far as the category is considered it needs to combine all unique categories when the records are not considered. If it is same dates then one of them needs to be picked.
ID Date Category Cycles
-------------------------------------------------
RYI19 6/12/2018 TEMPERATURE & VOLUME 1567
RYI19 6/25/2018 AREA 1890
RYI19 6/28/2018 TEMPERATURE 1435
TYI23 5/10/2020 LENGTH 1567
TYI23 6/12/2020 LENGTH 1678
I need to make sure to have only unique category in the field-Note that last record did not have LENGTH in the category twice.
Edit:
Adding rules clearly
1)If the dates are within 2 days or the cycles are within 100 cycles then remove the non- VOLUME record but if the categories are both VOLUME or both NON VOLUME records then display the prior date record.
2)If the temperature category is 10 days prior to the volume record then also consider the volume record only that is flag the temperature record to be removed/filtered.
3)If one of dates is in December then consider 30 days difference if the categories are different.
ID Date Category Cycles
RPI100 8/7/2020 Volume 4327
RPI100 8/18/2020 TEMPERATURE 4300
RDY234 6/1/2020 VOLUME 7014
RDY234 6/4/2020 TEMERATURE 7014
PDI23 8/3/2020 VOLUME 9799
PDI23 9/28/2020 TEMERATURE 12968
PDI23 10/6/2020 VOLUME 13398
F128 2/25/2020 TEMERATURE 9875
YU567 12/2/2020 VOLUME 7403
YU567 12/3/2020 VOLUME 7436
RTY78 8/17/2020 STATE 3198
TYI12 1/27/2020 VOLUME 6145
RPI145 12/16/2019 VOLUME 2110
RPI145 1/23/2020 TEMPERATURE 0
Something like this should do the trick
df.groupby(['id', 'date', 'cycles']).agg({"Category": " & ".join})

Determining Sick Periods from ranges

I have the below set of data which represents employee sick/absence days over a period (12 months) of time, in a table named Absence:
Day Date DaysSick OccasionsSick Notes
Tuesday 2016-09-27 1 Lisa A working today
Thursday 2016-09-29 1 Lisa sick today Celeste
Thursday 2017-01-05 1 Lisa sick today
I would like to update the OccasionsSick column based upon the instances of being sick. So i would have the following:
Day Date DaysSick OccasionsSick Notes
Tuesday 2016-09-27 1 1 Lisa A working today
Thursday 2016-09-29 1 Lisa sick today Celeste
Thursday 2017-01-05 1 1 Lisa sick today
So, the first two entries are the same period of sick leave, so i need a 1 in the first row, and the last entry is a separate sick period, so a 1 again.
Now, in order to establish a sick period there would be a reference to a roster table containing the below:
Date RosterType
2016-09-27 Sick
2016-09-28 Day Off
2016-09-29 Sick
2016-09-30 Normal
So the 27th and 29th were sick days, but the 28th was a standard day off, which is a likely occurrence, so using consecutive days is not an option. I need to be able to look for sick days until a "normal" RosterType is found, this then breaks the sick period. This 1 then needs to be assigned as per the desired result set.
What is the best way of updating the data here? I have come up with a big blank on this, apart from the logic of determining a sick period.
I am presenting this data in Excel with VBA, so it could also be easier to assign the sick periods in VBA, as opposed to SQL for the raw data
Please check this out.
This assumes that there is an entry in the roster for each day.
Basically I'm just building a period and counting the days in the roster.
If there are normal days in between it counts as a new period.
WITH CTE AS (
SELECT
[day]
,[date]
,LAG(date, 1) over (order by date) datebefore
,[dayssick]
FROM [dbo].[absence]
)
SELECT
*
,CASE WHEN ((SELECT COUNT(1) FROM [dbo].[rostertype] WHERE date < c.date AND date > c.datebefore AND rostertype = 'Normal') > 0
OR c.datebefore IS NULL) THEN 1 ELSE 0 END OccasionsSick
FROM CTE c