How to differentiate if difference between dates in weekly on monthly? - sql-server

I have a table in which employee's loan details are being saved. Some employee get loan on weekly basis and wish to return each installment weekly and some wish to return installments monthly.
I want to get the total duration on the loan period if employee wishes to return installments weekly then it should give output like 5 Weeks or 10 Weeks but if employee wishes to return installments monthly it should give result like 4 Months or 15 Months.
Here is the sample data
LoanID DueDate AmountToBePaid
2 2019-01-01 500
2 2019-01-07 500
2 2019-01-14 500
2 2019-01-21 500
2 2019-01-28 500
3 2019-01-01 1500
3 2019-02-01 1500
3 2019-03-01 1500
3 2019-04-01 1500
Here is what I've tried but it gives output in weeks no matter if the installments are to be paid monthly as for loan id 3.
SELECT
LoanId,
DATEDIFF(WEEK, inst_start, inst_end) weeks
FROM LoanMaster LM
INNER JOIN (
SELECT
dateadd(month, -1,min(duedate)) inst_start,
max(duedate) inst_end
FROM LoanDetail
) LD
ON LM.ID = LD.LoanID
Out should be like:
LoanId Duration
2 4 Weeks
3 3 Months

If your data strictly follow the rule that for the same LoanID the DueDates will be either only consecuctive weeks or only consecuctive months, then we can deduce the period by dividing the range with the row count:
SELECT
LoanID,
case
when datediff(month,min(DueDate),max(dueDate))=count(*)-1
then str(datediff(month,min(DueDate),max(dueDate)))+' Months'
else
str(datediff(week,min(DueDate),max(dueDate)))+' Weeks'
end as Duration
FROM LoanMaster LM
GROUP BY LOANID

Related

How to calculate periodIds using SQL server

I have a table1 which stores the data for multiple dates say (between 2022-01-01 to 2022-01-10) and I have another table2 which has time interval and has every 5mins information of dates available in table1 (i.e. 288 records for each day in above table).
Now, How I can write a query for table 2 to calculate time interval for each specific date in table 1. Say I need time intervals between
2022-01-01 12:00:00 to 2022-01-01 02:00:00
2022-01-02 00:05:00 to 2022-01-02 23:00:00
2022-01-04 00:05:00 to 2022-01-10 15:00:00
I tried using DATEDIFF function but that is not giving the results. let's say If I take date 2022-01-02 00:00:00 then my time interval should go back to 1 it should be 2 for 2022-01-02 00:05:00
Below is the example of data:
Table 1:
ID Start date End date
20030917.D0001 2003-09-17 14:10:00 2003-09-18 14:20:00
Table 2:
Date Time interval Amount
2003-09-17 1 150
2003-09-17 2 100
2003-09-17 3 200
2003-09-17 288 250
2003-09-18 1 250
2003-09-18 2 300
2003-09-18 3 1100
2003-09-18 288 150
The time interval in table 2 is every 5 mins of that particular date. Now I need to fetch the data from table 2 which matches with specific date and time in table1
i'm guessing here, if you are looking to return data from table2 with specific time and the table formatted like below
table1
tbl1id
Date
1
2022-01-01
2
2022-01-10
table2
tbl2id
tbl1id
Time
1
1
12:00:00
2
1
12:05:00
3
1
12:10:00
your query should be
select *
from table2
where Time between '12:00:00' and '02:00:00'
and tbl1id
in
(
select tbl1id
from table1
where Date = '2022-01-01'
)
however it you are looking for just looking for calculate time interval in Minute
DECLARE #startdate DATETIME2 = '2022-01-02 00:00:00';
DECLARE #enddate DATETIME2 = '2022-01-02 00:05:00';
SELECT DATEDIFF(Minute, #startdate, #enddate);
that should do it.

How to get the sum of each salary which is order by week?

I have a table like this
Input Table -
Date Salary
2020-01-01 00:00:00.000 2321
2020-01-02 00:00:00.000 2414
2020-01-03 00:00:00.000 2323
2020-01-04 00:00:00.000 2324
2020-01-05 00:00:00.000 2325.....so on
I have written a query but this query is only giving the sum of previous two weeks for which I have used LAG function
SELECT DATENAME(MONTH,Date) Months,
DATEPART(WEEK,Date) as WeekNo,
SUM(Salary) Salary,
WeekSalary= LAG(SUM(salary)) OVER (PARTITION BY Datepart(Month,Date) ORDER BY DATEPART(MONTH,Date))+SUM(salary)
FROM SheetTable
GROUP BY DATEPART(WEEK,Date),DATENAME(MONTH,Date)
Output:
Months Week Salary WeekSalary
January 1 9382 NULL
January 2 11681 21063
January 3 55245 66926
January 4 90939 146184
January 5 14091 105030
February 5 2352 NULL
February 6 16492 18844
February 7 16541 33033
February 8 16590 33131
February 9 16639 33229
March 10 16685 NULL
March 11 16730 33415
March 12 16779 33509
March 13 16828 33607
March 14 7227 24055
April 14 9650 NULL
April 15 7248 16898
but what if I need a column of total salary till week-
I tried this query
SELECT DATENAME(MONTH,Date) Months,
DATEPART(WEEK,Date) as WeekNo,
SUM(Salary) Salary,
TotalSalary=SUM(salary) OVER (ORDER BY Datepart(week,Date) ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)
FROM SheetTable
GROUP BY DATEPART(WEEK,Date),DATENAME(MONTH,Date)
but this getting error:
Column 'SheetTable.salary' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause.
Expected:
Months Week Salary TotalSalary
January 1 9382 9382 --Week(1)
January 2 11681 21063 --week(1+2)
January 3 55245 76308 --week(1+2+3)
January 4 90939 167247--week(1+2+3+4)...so on
You should be able to achieve what you need by using a frame like so:
SUM(SUM(salary)) OVER (ORDER BY Date ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)

Creating Monthly Data From Seasonal Factors and Annual Data

I have two tables:
table of multiplicative seasonal factors for each month
table of annual budget amounts
I would like a T-SQL solution to create a third table that explodes (multiplies) the annual budget amounts into a monthly time series.
Example of Table 1 (seasonal factors):
Month
Seasonal Factor
1
.08
2
.075
3
.065
4
.085
5
.09
6
.08
7
.08
8
.075
9
.065
10
.085
11
.09
12
.13
Example of Table 2 (annual budget amounts)
Year
Budget
2019
250,000
2020
275,000
Desired Solution
Month
Imputed Budget
2019-01-01
.08 * 250,000
2019-02-01
.075 * 250,000
...
...
2020-12-01
.13 * 275,000
You seem to be describing a cross join:
select datefromparts(t2.year, t1.month, 1) as month,
t1.factor * t2.budget
from table1 t1 cross join
table2 t2
order by month;

Calculating number of con-consecutive total years donated in SQL

I have some sample donation history:
ID TransactionDate Amount
10 2001-12-19 00:00:00.000 75.00
10 2001-07-11 00:00:00.000 760.00
10 2010-10-15 00:00:00.000 2200.00
10 2012-08-15 00:00:00.000 1220.00
10 2013-09-16 00:00:00.000 610.00
100 2000-09-26 00:00:00.000 3000.00
100 1999-01-01 00:00:00.000 5000.00
I am trying to get a summary of giving by year by donor. The total does not have to be for consecutive years, but will just total overall # of years given. The total does not need to equal the number of transactions per year, just that the ID donated in that particular year.
For instance, ID 10 above would equal 4 indicating giving in 4 calendar years (2 donations in 2001, 1 in 2010, 1 in 2012, and 1 in 2013). ID 100 would equal 2.
The donations date back many years, so hard-coding dates is not very feasible.
Any ideas are appreciated.
Try this:
SELECT ID, DATEPART(yy,TransactionDate) Year, COUNT(*)
FROM tableName
GROUP BY ID, DATEPART(yy,TransactionDate)
You just need to return and then group on the relevant parts of your data, which is the ID and the year of the TransactionDate:
select d.ID
,count(1) as DonationYears
from(select distinct ID -- Sub query returns one row per ID and Year, which is counted up by ID in the outer query
,year(TransactionDate) as TranYear
from Donations
) d
group by d.ID

Split a particular month into weeks and days

Suppose I took the month November.I need to display first row as shown below.The rest of the rows should be the data from database.The rows display post date and amount and if data is present on those dates,it should be shown.I also need to show the weekly totals and monthly totals of the amounts taken.This is shown for a PARTICULAR MONTH of a PARTICULAR YEAR.
I was planning to write a query for the data and implement it in Telerik via crosstab.Please give your thoughts on the same.
Input:-
POST DATE Amount($)
2013-11-01 00:00:00.000 50.00
2013-11-04 09:30:12.000 10.00
2013-11-05 11:04:00.000 20.00
2013-11-06 00:00:00.000 30.00
2013-11-07 00:00:00.000 40.00
2013-11-08 00:00:00.000 10.00
2013-11-11 00:00:00.000 10.00
2013-11-12 00:00:00.000 10.00
2013-11-15 00:00:00.000 10.00
.
.
.
The data(for the month November) should be visible like this:-
01-Nov Weekly Total 04-Nov 05-Nov 06-Nov 07-Nov 08-Nov Weekly Total 11-Nov 12-Nov 13-Nov 14-Nov 15-Nov Weekly Total 18-Nov 19-Nov 20-Nov 21-Nov 22-Nov Weekly Total 25-Nov 26-Nov 27-Nov 29-Nov Weekly Total MTD Total
50$ 50$ 10$ 20$ 30$ 40$ 10$ 110$ 10$ 10$ 10$ 30$
Thanks in advance
MSDN Date and Time Data Types and Functions (Transact-SQL)
DECLARE #TempTrans AS Table (
ID INT NOT NULL IDENTITY PRIMARY KEY
,DateTimeTrans DATETIME NOT NULL
,Amount MONEY NOT NULL
)
INSERT INTO #TempTrans (DateTimeTrans, Amount)
VALUES ('20131101', 50)
,('20131104 09:30:12',10)
,('20131104 11:04:00',15)
,('20131105',20)
,('20131106',30)
,('20131111',10)
,('20131115',80)
,('20131119',70)
,('20131123',60)
,('20111129 10:08:04',25)
SELECT *
,CASE
WHEN [weekNumber] IS NULL AND [Date] IS NULL THEN 'MTD Total'
WHEN [Date] IS NULL THEN 'Weekly Total'
ELSE CAST([Date] as varchar(30))
END as [Description]
FROM (
SELECT DATEPART(week,DateTimeTrans) as weekNumber,CAST(DateTimeTrans as date) as Date, SUM(Amount) as Amount
FROM #TempTrans
WHERE DATEPART(MONTH,DateTimeTrans) = 11
GROUP BY DATEPART(week,DateTimeTrans) ,CAST(DateTimeTrans as date)
WITH Rollup
) grp
GO

Resources