SQL Server: check if certain date in calendar table falls on a weekend - sql

I have created a calendar table that contains all the calendar dates of a year, incl. the corresponding quarter / week / month / day etc. information.
The following Select gives me a specific date, here the 17th of March.
How can I extend the below to check if this falls on a Saturday or Sunday (weekDayCal = 7 or 1) and, if true, return the date for the following Monday, otherwise return the 17th ?
SELECT *
FROM Calendar
WHERE (yearCal = 2014) AND (monthCal = 3) AND (dayCal = 17)
Many thanks in advance for any help with this, Mike.

Assuming you have a day_of_calendar style id field, where every date is sequentially in order, then this works...
SELECT *
FROM Calendar
WHERE id = (SELECT id + CASE weekDayCal WHEN 7 THEN 2 WHEN 1 THEN 1 ELSE 0 END
FROM Calendar
WHERE (yearCal = 2014) AND (monthCal = 3) AND (dayCal = 17)
)
If not, then you're going to have to return to using dates in one way or another.
For example...
SELECT *
FROM Calendar
WHERE realDate = (SELECT realDate + CASE weekDayCal WHEN 7 THEN 2 WHEN 1 THEN 1 ELSE 0 END
FROM Calendar
WHERE (yearCal = 2014) AND (monthCal = 3) AND (dayCal = 17)
)
But then you may as well just use real date calculations.

I think this should work, if you do indeed have a weekDayCal column where 1=Sunday, 2 = Monday and 7 = Saturday:
SELECT *
FROM Calendar
WHERE (yearCal = 2014) AND (monthCal = 3) AND (
(dayCal = 17 and weekDayCal not in (1,7)) OR
(dayCal = 17 + 1 and weekDayCal = 2) OR
(dayCal = 17 + 2 and weekDayCal = 2))

This fetches rows who fall on sunaday or saturday
SELECT *
FROM Calender
WHERE DATEPART(dw, CAST(
CAST(monthCal as VARCHAR(2))+ '-'+
CAST(dayCal as VARCHAR(2))+'-'+
CAST(yearCal as VARCHAR(4))
AS DATETIME
)
) IN(1,7)

Related

Make a case with several results SQL TERADATA

I am looking to make a case in a SQL query and assign according to the condition several results.
For example :
Code :
INSERT INTO DESTINATION_TABLE (DT_TRT, NU_QUARTER, NU_YEAR) VALUES
(SELECT
CASE
WHEN #P_DT_TRT# = '1900-00-00'
THEN MAX(TT.DT_CTTT)
ELSE #P_DT_TRT#
END AS DT_TRT,
CASE
WHEN EXTRACT (MONTH FROM DT_TRT) < 4
THEN NU_QUARTER = 4 AND NU_YEAR = EXTRACT (YEAR FROM DT_TRT) - 1
ELSE NU_YEAR = EXTRACT (YEAR FROM DT_TRT)
END
CASE
WHEN EXTRACT (MONTH FROM DT_TRT) < 7
THEN 1
ELSE (CASE WHEN EXTRACT (MONTH FROM DT_TRT) < 10 THEN 2 ELSE 3 END AS NU_QUARTER)
END AS NU_QUARTER
FROM TARGET_TABLE TT);
Algorithm :
-> A date will be given in the programme to enable the calculation (#P_DT_TRT#)
If the parameter is not supplied (value = 1900-00-00)
DT_TRT = the largest constitution date (DT_CTTT) in the target table (TARGET_TABLE TT)
Otherwise DT_TRT = date given in parameter
If DT_TRT month < 4
Quarter = 4
Year = Year of DT_TRT - 1
Otherwise Year = Year of DT_TRT
If DT_TRT month < 7
Quarter = 1
Otherwise
If DT_TRT < 10
Quarter = 2
Otherwise Quarter = 3
Question : Is it possible to integrate several results (DT_TRT, NU_QUARTER, NU_YEAR) in one case ? And if so, what is the syntax ?
I work in Teradata Studio.
Thank you for your answers. :)
This seems to be your logic:
INSERT INTO DESTINATION_TABLE (DT_TRT, NU_QUARTER, NU_YEAR)
VALUES
(
-- If the parameter is not supplied (value = 1900-00-00)
-- DT_TRT = the largest constitution date (DT_CTTT) in the target table (TARGET_TABLE TT)
-- Otherwise DT_TRT = date given in parameter
CASE
WHEN #P_DT_TRT# = '1900-00-00'
THEN (SELECT Max(DT_CTTT) FROM TARGET_TABLE)
ELSE #P_DT_TRT#
END,
-- shift back year/quarter by three months to adjust for company's business year
td_quarter_of_year(Add_Months(DT_TRT, -3)),
Extract(YEAR From Add_Months(DT_TRT, -3))
)
;

Need store procedure to calculate from these two tables

I should do this in xampp need an sp structure for this as i am a beginner if possible help to give complete sp for this scenario with detailed explanantion. Other structure like crud operations has been done with php,javascript
1. SELECT `cid`, `parent_cat`, `category_name`, `category_life`, `status` FROM `categories`
2. SELECT `pid`, `cid`, `bid`, `product_name`, `product_price`, `product_stock`, `added_date`, `p_status`, `loc`, `in_no`, `gst_no`, `cgst`, `sgst`, `igst`, `total`, `depre`, `pur_from` FROM `products`
From the above two table's i should fetch record and calculate those fields and insert in the below table:
3. SELECT `elapsed_yend`, `remaining_days`, `depreciation_cur`, `current_wdv`, `depreciation_next`, `next_wdv`, `accumulate_depre`, `sale_amount`, `pro_los`, `end_date` FROM `calculation`
Example, these calculation should happen in products table:
CGST:
cgst = product_price * 09
sgst = product_price * 09
igst = product_price * 09
if status is 1 it should calculate igst other cgst,sgst must be 0(zero)
0 it should calculate cgst,sgst other igst must be 0(zero)
Depreciation Amount:
depre = product_price + .5(cgst+sgst+igst)
Elapsede year end :
elapsed_yend = added_date(from products table (No:2)) till every year 31/March/xxxx.
Number of days between these two dates
remaining_days = category_life - (date difference between added_date(from products (No:1)) till date)
category_life(from categories table (No:1))Ex:mobile it's life will be 1080 days.
Current Year depreciation:
depreciation_cur = (depre/category_life)*elapsed_yend
Current Year Written down value:
current_wdv = depre - depreciation_cur
Next Year depreciation :
depreciation_next = (depre / category_life) * D
D = days difference between every year 01/April/xxxx till end_date(from calculation table)
Next Year Written down value:
next_wdv = current_wdv - depreciation_next
Accumulate Depreciation :
accumulate_depre = depreciation_cur + depreciation_next
I have cracked it and it is working fine as of now.
BEGIN
DECLARE cur_depre,cur_wtvalue,next_depre,next_wtvalue,accum_depre,pro_loss double(20,2);
DECLARE days,next_diff int;
CREATE TABLE IF NOT EXISTS calc AS (SELECT p.pid,p_date,days,next_diff,cur_depre,cur_wtvalue,next_depre,next_wtvalue,accum_depre,pro_loss,c.cid,p.added_date,c.category_life,p.depre,p.sale_status,p.sale_date,p.sale_amount from products p,products d,categories c WHERE p.pid=d.pid AND p.cid=c.cid
);
INSERT INTO calc (PID)
SELECT PID FROM products WHERE PID NOT IN (SELECT PID FROM calc);
UPDATE calc set days = datediff(p_date,added_date);
UPDATE calc set days = 0 WHERE datediff(p_date,added_date) < 0;
UPDATE calc set next_diff = datediff(sale_date,DATE_ADD(p_date, INTERVAL 1 DAY) );
UPDATE calc set next_diff = datediff('2019-03-31',added_date) WHERE added_date>p_date;
UPDATE calc set cur_depre = (depre/category_life)*datediff(p_date,added_date);
UPDATE calc set cur_depre = 0 where (depre/category_life)*datediff(p_date,added_date)<0;
UPDATE calc set cur_wtvalue =(depre-(depre/category_life)*datediff(p_date,added_date));
UPDATE calc set cur_wtvalue = 0 WHERE added_date>p_date;
UPDATE calc set next_depre =( (depre/category_life)*datediff(sale_date,DATE_ADD(p_date, INTERVAL 1 DAY) )) where added_date < p_date;
UPDATE calc set next_depre =( (depre/category_life) * datediff('2019-03-31',added_date)) WHERE added_Date > p_date;
UPDATE calc SET next_wtvalue = depre -(depre/category_life)*datediff(p_date,added_date) - (( (depre/category_life)*datediff(sale_date,DATE_ADD(p_date, INTERVAL 1 DAY) )) );
UPDATE calc SET next_wtvalue = depre - (( (depre/category_life) * datediff('2019-03-31',added_date))) WHERE added_date>p_date;
UPDATE calc SET accum_depre = ((depre/category_life)*datediff(p_date,added_date))+( (depre/category_life)*datediff(sale_date,DATE_ADD(p_date, INTERVAL 1 DAY) )) ;
UPDATE calc SET accum_depre =( (depre/category_life) * datediff('2019-03-31',added_date)) WHERE added_Date > p_date;
UPDATE calc SET pro_loss = sale_amount-(depre -(depre/category_life)*datediff(p_date,added_date) - (( (depre/category_life)*datediff(sale_date,DATE_ADD(p_date, INTERVAL 1 DAY) )) ) );
UPDATE calc SET pro_loss = 0 WHERE sale_status=0;
SELECT * from calc;
END

SQL Query to retrieve users based on date and month

I have the following table:
User
UserID
CompanyID
Name
IsActive
Date_Joined
Date_Left
I'm trying to get a query to get the billable users, criteria being:
A user that joined the month of billing, is not seen as a billable user.
A user that left on the month of billing, is a billable user.
I have the following query:
SELECT * from user u WHERE CompanyID = 1205
AND (p.IsActive = 1 AND MONTH(p.Date_Joined) != MONTH(GETDATE())
OR (p.is_active = 0 AND MONTH(p.Date_Left) = MONTH(GETDATE())
The problem is that this query isn't working as it doesn't check the year of the user (users joined in september 2017 are not seen as billable, even though they should as they were joined in 2017 and not this year, the persons who are created in september 2018 should not be seen as billable).
How can I implement the year or optimize my query?
EOMONTH can be used to determine the last day of month. For example:
/* last day of prev month */ EOMONTH('2018-09-05', -1) = 2018-08-31
/* last day of curr month */ EOMONTH('2018-09-05') = 2018-09-30
You can easily check if active user joined on previous month(s) or inactive user left on current month as follows:
DECLARE #billdate AS DATE = '2018-09-05';
SELECT *
FROM user
WHERE CompanyID = 1205 AND (
(
IsActive = 1 AND
Date_Joined <= EOMONTH(#billdate, -1)
)
OR
(
IsActive = 0 AND
Date_Left > EOMONTH(#billdate, -1) AND
Date_Left <= EOMONTH(#billdate)
)
)
I think your parenthesis are off. Putting them around an AND doesn't do anything. You probably wanted to put them around the OR.
There is no target table for the alias p. From the column names I think the columns prefixed with it are also from user, so change the alias to u.
And to check the year you can use year() similar to how you used month().
SELECT *
FROM user u
WHERE u.companyid = 1205
AND (u.isactive = 1
AND month(p.date_joined) != month(getdate())
AND year(p.date_joined) = year(getdate())
OR u.is_active = 0
AND month(p.date_left) = month(getdate())
AND year(p.date_left) = year(getdate()));
I think you need check between current month start date and End date.
Try this
DECLARE #D_FROM_DATE DATE,#D_TO_DATE DATE
SELECT #D_FROM_DATE=DATEADD(DAY,-DATEPART(DAY,GETDATE()-1),GETDATE()),
#D_TO_DATE=DATEADD(MONTH,1,DATEADD(DAY,-DATEPART(DAY,GETDATE()),GETDATE()))
SELECT * FROM USER P
WHERE P.COMPANYID = 1205
AND
(
CAST(P.DATE_JOINED AS DATE) BETWEEN #D_FROM_DATE AND #D_TO_DATE
OR
CAST(P.DATE_LEFT AS DATE) BETWEEN #D_FROM_DATE AND #D_TO_DATE
)
You can use like this
SELECT * from user u WHERE CompanyID = 1205
AND (p.IsActive = 1 AND CONCAT(YEAR(p.Date_Joined),'/',MONTH(p.Date_Joined)) != CONCAT(YEAR(GETDATE()),'/',MONTH(GETDATE())))
OR (p.is_active = 0 AND CONCAT(YEAR(p.Date_Left),'/',MONTH(p.Date_Left)) = CONCAT(YEAR(GETDATE()),'/',MONTH(GETDATE())))

Birthday reminder in SQL Server

I want to select those people whose date of birth matches with current system date.
My SQL query is:
select testtable.task
from testtable
where testtable.dates like (select SUBSTRING(CONVERT(varchar(10), GETDATE(), 10), 1, 5))
I have written this in SQL Server.
The issue is it is not returning any data but the inner subquery is working perfectly fine.
Please specify the solutions for both the cases when date is stored as a string and when date is stored as date type.
Thanks in advance
Assuming testtable.dates is of type Date DateTime or DateTime2, you can simply use this query:
select testtable.task
from testtable
where month(testtable.dates) = month(getdate())
and day(testtable.dates) = day(getdate())
Accepted solution doesn't take into account Leap years, so if someone birthday is on the 2020-02-29 he will only get a notification every 4 years.
This query returns on non leap years the 02/29 birthdays on the 02/28 like most countries and social medias.
MariaDB/MySQL:
SELECT
*
FROM
Employees
WHERE
CASE
WHEN MONTH(CURDATE()) = 2 AND DAY(CURDATE()) = 28
AND DAY(ADDDATE(CURDATE(), 1)) != 29
THEN MONTH(Employees.DateOfBirth) = 2 AND
DAY(Employees.DateOfBirth) IN (28, 29)
ELSE MONTH(Employees.DateOfBirth) = MONTH(CURDATE()) AND
DAY(Employees.DateOfBirth) = DAY(CURDATE())
END
MsSQL:
SELECT
*
FROM
Employees
WHERE
(MONTH(GETDATE()) = 2 AND DAY(GETDATE()) = 28 AND DAY(DATEADD(day, 1, GETDATE())) != 29) AND
(MONTH(Employees.DateOfBirth) = 2 AND DAY(Employees.DateOfBirth) IN (28, 29))
OR
NOT (MONTH(GETDATE()) = 2 AND DAY(GETDATE()) = 28 AND DAY(DATEADD(day, 1, GETDATE())) != 29) AND
(MONTH(Employees.DateOfBirth) = MONTH(GETDATE()) AND DAY(Employees.DateOfBirth) = DAY(GETDATE()))

Unsure what SQL query is attempting to do

I am working on some inherited code, and am having an issue with an SQL Query within it. The query is as follows.
Select distinct
g.scriptid,
g.procedurename,
h.parameters,
g.scriptname,
h.usercode,
h.facility,
h.recid,
cast((cast(recid as varchar) + '.' + Right('0000' + cast(scriptgennum as varchar), 4)) as decimal(10,4)) as 'scriptrecid',
scriptgennum+1 as 'scriptgennum',
h.generated,
h.runinterval,
case
when runinterval = 'M' then dateadd(month,1,convert(varchar(10),h.nextrundate,120))
when runinterval = 'Q' then dateadd(month,3,convert(varchar(10),h.nextrundate,120))
when runinterval = 'W' then dateadd(week,1,convert(varchar(10),h.nextrundate,120))
when runinterval = '0' then NULL end as 'nextrundate',
convert(varchar(10),getdate(),120) as currentrundate,
scripttype
from PATIENTLETTERS_SCRIPTHIST h join PATIENTLETTERS_SCRIPTS g on
g.scriptid = h.scriptid where
h.status = 'Y'
and (([runinterval] = 'M'
and (convert(varchar(10),nextrundate,120) = convert(varchar(10),getdate(),120)
and datepart(day,getdate()) = 5
and (datediff(month,convert(varchar(10),h.lastrundate,120),convert(varchar(10),getdate(),120)) = 1)
or lastrundate is null))
or ([runinterval] = 'Q'
and (convert(varchar(10),nextrundate,120) = convert(varchar(10),getdate(),120)
and datepart(weekday,getdate()) = 0
and (datediff(month,convert(varchar(10),h.lastrundate,120),convert(varchar(10),getdate(),120)) = 3)
or lastrundate is null))
or ([runinterval] = 'W'
and (convert(varchar(10),nextrundate,120) = convert(varchar(10),getdate(),120)
and datepart(day,getdate()) = 5
and (datediff(week,convert(varchar(10),h.lastrundate,120),convert(varchar(10),getdate(),120)) = 1)
or lastrundate is null))
or ([runinterval] = 'O'
and (convert(varchar(10),nextrundate,120) = convert(varchar(10),getdate(),120)
and (datepart(weekday,getdate()) = 0))
or lastrundate is null))
I know that it is trying to select the specific columns listed from PATIENTLETTERS_SCRIPTHIST and PATIENTLETTERS_SCRIPTS. The part of the query that has me confused are the lines like these:
and (([runinterval] = 'M'
and (convert(varchar(10),nextrundate,120) = convert(varchar(10),getdate(),120)
and datepart(day,getdate()) = 5
and (datediff(month,convert(varchar(10),h.lastrundate,120),convert(varchar(10),getdate(),120)) = 1)
If someone can explain what those lines are actually doing I would greatly appreciate any help. I can see that it wants to make sure that the run interval is 'M', and it looks like its trying to match up the current date to the day in stored in the database in the 4th line, but the 2nd and 3rd lines are still a complete mystery.
Looking for items set to run monthly, where the next run date is today, and today is the 5th of the month, and it's been exactly one month since the item was last run.
More info on CONVERT
and DATEPART
This code is looking for items that have a runinterval = 'M'
line 1 - [runinterval] = 'M'
and the nextrundate is equal to the current date (getdate()), the dates are being converted to a varchar with the same formatting.
line 2 - and (convert(varchar(10),nextrundate,120) = convert(varchar(10),getdate(),120)
and the current date has a day equal to 5. Meaning that the date would have to be June 5, July 5, etc
line 3 - and datepart(day,getdate()) = 5
and the difference between the month of the lastrundate and the current date (getdate()) is equal to 1
line 4 - (datediff(month,convert(varchar(10),h.lastrundate,120),convert(varchar(10),getdate(),120)) = 1)
The second line converts nextrundate and the current date to 'YYYY-MM-DD' format using style 120 (More details here) then checks that they're the same, so only rows where nextrundate is today.
The third line just checks that today is the 5th day of the month. For instance:
SELECT DATEPART(DAY, '2012-07-05') returns 5.