dateadd and between in SQL Query - sql

I have a SQL query that prompts for a startdate and enddate, Between #startdate And #enddate. But what I am trying to do is have the same query automatically look 3 months forward from today's month using a dateadd / getdate code, but can not figure out how to integrate the two?

In sql-server, which I assume because you are referencing GETDATE() and DATEADD()
DATEADD(MONTH,3,GETDATE())
IN Oracle based on Why is the GETDATE() an invalid identifier, and Equivalent function for DATEADD() in Oracle
ADD_MONTHS(SYSDATE,3)
Based on your comment and if Siebel is on sql-server you would need
Where vwS_CoPrimPolicy.S_PrimPolicyExpDT Between #startdate And #enddate And vwS_Co.S_CoStatus = 'Customer' And vwS_Co.S_CoType = 'Automotive
to become
where vwS_CoPrimPolicy.S_PrimPolicyExpDT Between
DATEFROMPARTS(YEAR(DATEADD(MONTH,3,GETDATE())),MONTH(DATEADD(MONTH,3,GETDATE())),1)
AND DATEADD(DAY,-1,DATEFROMPARTS(YEAR(DATEADD(MONTH,4,GETDATE())),MONTH(DATEADD(MONTH,4,GETDATE())),1))
And vwS_Co.S_CoStatus = 'Customer' And vwS_Co.S_CoType = 'Automotive
To Break that down a little because you are actually looking for the start of the month 3 months from today to the end of the month 3 months from today and those months could be 28,29,30,or 31 days long you actually need to find the date 3 months ahead then get the beginning of the month DATEFROMPARTS() is useful for that. Then for the end of the month, find the date 4 months out and go back a day.

Related

How to decipher complex DATEADD function from MS Access

I have inherited a query from an old MS Access DB and cannot for the life of me figure out what was trying to be done in this date parameter function. I normally only use SQL and this seems a bit different. Can any one assist in describing what this logic is doing?
use pdx_sap_user
go
select po_number,
po_issue_date
from vw_po_header
where po_issue_date > getDate() And PO_issue_date < DateAdd("d",-1,DateAdd("m",8,DateAdd("d",-(Day(getDate())-1),getDate())))
You can de-obfuscate it a lot by using DateSerial:
where
po_issue_date > getDate() And
po_issue_date < DateSerial(Year(getDate()), Month(getDate()) + 8, 0)
First: there is no getDate() function in Access. Probably it should be Date() which returns the current date.
Now starting from the inner expression:
Day(Date()) returns the current day as an integer 1-31.
So in DateAdd("d", -(Day(Date())-1), Date()) from the current date are subtracted as many days as needed to return the 1st of the current month.
Then:
DateAdd("m", 8, DateAdd("d", -(Day(Date())-1), Date()))
adds 8 months to the the 1st of the current month returning the 1st of the month of the date after 8 months.
Finally:
DateAdd("d", -1,...)
subtracts 1 day from the date returned by the previous expression, returning the last day of the previous month of that date.
So if you run today 13-Sep-2019 this code, the result will be:
30-Apr-2020
because this is the last day of the previous month after 8 months.
I think the following:
Take the current date
Substract the current day of month -1 to get the first day of current month
Add 8 month to this
Substract 1 day to get the last day of the previous month
So it calculates some deadline in approx 8 months.
But I wonder how a PO issue date can be in the future...

How to write a variable within SQL using Dateadd and DateDiff for finding the last TWO days of the previous month

I am trying to write a variable using the dateadd and datediff that shows the last two days of previous month. One variable will be the second to last day of the previous month, the one I am having trouble with. The other will be the last day of the previous month, the one I was able to get. I am using SQL Server.
I've tried looking for it on Stack and I have only seen the last day of the previous month given and NOT the second to last day. I tried learning the dateadd and datediff, (which I still want to do).
This is what I tried so far:
Declare #CurrentMonth as date = '3/1/2019'
Declare #SecLastDayPrevMonth as date = DATEADD(MONTH, DATEDIFF(MONTH, 0, #currentmonth), -2)
Declare #LastDayPrevMonth as date = DATEADD(MONTH, DATEDIFF(MONTH, 0, #currentmonth), -1)
The results I am getting for the seclastdayPrevMonth is 2/28/2019. Instead I would want 2/27/2019
I am also getting 2/28/2019 for lastdayprevmonth which is what I want.
I am writing variables because the current month will change every month, and instead of having to update the other days I need within my query, I want to use variables so I am only updating the current month and everything else is flowing through.
And explanation as to why my dateadd/datediff is wrong and an explanation for why the correct dateadd/datediff is the way it is, will be very helpful
Why not refer to the last day when calculating the second last day? Also, your usage of DATEADD is very weird. The syntax is DATEADD(interval, increment, datetime)
Declare #recmonth as date = '3/1/2019'
Declare #LastDayPrevMonth as date = EOMONTH(DATEADD(MONTH, -1, #RecMonth))
Declare #SecLastDayPrevMonth as date = DATEADD(DAY, -1, #LastDayPrevMonth)
SELECT #SecLastDayPrevMonth, #LastDayPrevMonth
So we can calculate the last day of the previous month by subtracting one month from a date and then calling EOMONTH, which returns the last day of a given month. Then the second last day is just subtracting one day from that.
Yields:
SecLastDayPrevMonth LastDayPrevMonth
------------------- ----------------
2019-02-27 2019-02-28
As to "why", DATEDIFF() takes 3 arguments: datepart (string representation of a specific date part), startdate, enddate (both of which must be convertible to a date-ish object).
0 is essentially SQL's epoch, which, in this case is 1/1/1900. So the difference in months between 0 and 3/1/2019 is (119*12)+2 (+2 because we exclude March, since we aren't calculating a full month) = 1430 months difference.
Then, we are trying to add 2 months to our value. DATEADD() takes 3 arguments: datepart, number, date. But, in the example, you are adding 1430 months to whatever date -2 gets converted to (in this case, I believe it would be 12/30/1899, or 2 days before epoch). So, 1430 months after 12/30/1899 would be 2/30/2019, but February only has 28 days in 2019, so it returns 2/28/2019. In a Leap Year, it probably would return 2/29/2019.
To get your #LastDayPrevMonth and #SecLastDayPrevMonth with only DATEDIFF() and DATEADD(), you just need to change your calculations a little.
First thing you want to do is find the First Day of your Given Month. That can be done with DATEADD(month,DATEDIFF(month,0,#CurrentDate),0). We're essentially using the same thing we used above to calculate the number of months since epoch, but then we are adding those months back to epoch.
Now that we know the First Day of the Given Month, all we have to do is subtract days to get a day from the prior month.
So,
DECLARE #CurrentDate date = '2019-03-15' ; -- Changed it to something in the middle of the month.
DECLARE #FirstDayOfGivenMonth = DATEADD(month,DATEDIFF(month,0,#CurrentDate),0) ; -- 3/1/2019
DECLARE #LastDayOfPrevMonth date = DATEADD(day,-1,#FirstDayOfThisMonth) ; -- 2/28/2019
DECLARE #SecLastDayOfPrevMonth date = DATEADD(day, -2, #FirstDayOfThisMonth) ; -- 2/27/2019
SELECT #LastDayOfPrevMonth AS LDPM, #SecLastDayOfPrevMonth AS SLDPM ;
DECLARE #FourDaysLeftInPrevMonth date = DATEADD(day, -4, #FirstDayOfThisMonth) ; -- 2/25/2019
SELECT #FourDaysLeftInPrevMonth AS FourDaysLeftPrev ;
Granted, since SQL 2012, this can all be accomplished much easier with the EOM() function to get to the last day of a month. But if you only could use the two original functions from your original question, this would be one way to get to your needed values.

Pulling records based on Date in JDBC

How can I return all customers whose last appointment_date was 11 months ago from the date today? Or 12 months ago from the date in a month from today?
The first statement is working where I get the appointment from_date and compare it to the current date and return all the appointments that are happening tomorrow:
SELECT appointment.id,
appointment.from_date
WHERE (julianday('now') - julianday(appointment.from_date)) = 1
But for the second statement I cant figure out how to return all customers whose last appointment date was 11 months ago from the current date?
SELECT customer.id,
customer.last_appointment_date
FROM customer
WHERE datediff(month, customer.last_appointment_date, DATEADD(month, getDate())) = 12
datediff() doesn't work because I am using SQLite and it is not a recognised function.
Any help would be greatly appreciated.
EDIT: I am running these query's in my code in netbeans i am using the sqllitejdbc driver to run them through prepared statements
I have edited, its because i am running through netbeans, everytime i use datediff(month, customer.last_appointment_date, DATEADD(month, getDate())) = 12 it returns month not a valid column - it doesnt recognise it as a valid date part?
returned: Caused by: java.sql.SQLException: [SQLITE_ERROR] SQL error or missing database (no such column: month)
Calculate the date to compare your field with, instead of calculating the difference and comparing to a constant, that way the database can make use of an index to locate records.
Use the date function instead of dateadd (see SQLite equivalent of SQL Server DateAdd function):
SELECT customer.id,
customer.last_appointment_date
FROM customer
WHERE customer.last_appointment_date = date('now', '-11 month')

Values over a time period

I would like to calculate a value in SQL that does the following:
if the user's inputted month parameter (I'm writing the SQL to aggregate information first then using SSRS) is 90 days or more past today (or the most recent data entry), then use the value for that month. Otherwise, if the month parameter is within 90 days of the report run date (or most recent data entry), use the most recent value that IS in fact 90 days past. For example, if I run the report in August and specify the month parameter as August, I will want the value from May. If I specify the month parameter as April, I want April's value since 90 days has gone by since then. Apologies if this isn't concise. I just would like some direction.
Cheers.
As suggested by #DanBracuk in the comments, you should probably take the parameter from SSRS and just update it based on the current date in your T-SQL code.
Say you have an SSRS parameter Parameters!Month.Value which gets passed to your stored procedure as #Month.
You can use GETDATE() and date functions like DATEDIFF() and DATEADD() to adjust #Month as required, e.g. in the stored procedure code something like:
select #Month = case when datediff(dd, #Month, getdate()) > 90
then #Month
else dateadd(dd, -90, #Month)
end
select *
from MyTable
where MyDate < #Month
Update the first statement to meet your requirements; they seem a bit ambiguous at this point - apologies if I haven't understood the issue completely.

Getting week number of date in SQL

Is there a way to get the week number of a date with SQL that is database independent?
For example to get the month of a date I use:
SELECT EXTRACT(MONTH FROM :DATE)
But the EXTRACT function doesn't know about weeks in SQL92.
Please pay attention to the fact that I want a solution that is database independent! Do not misinterpret this as a question regarding MS SQL Server.
There doesn't appear to be a single standard SQL function to extract the week number from a date - see here for a comparison of how different SQL dialects can extract different dateparts from date fields.
You can try this.
declare #date datetime
select #date='2013-03-15 00:00:00'
select 'Week No: '+ convert(varchar(10),datepart(wk,#date)) as weekno
Try this one :
SELECT DATENAME(yy,GETDATE())+RIGHT(DATENAME(wk,GETDATE()),2)
To understand DATENAME, please follow this link : sqltutorials.blogspot.be/2007/05/sql-datename.html and for the right, suite101.com/article/sql-functions-leftrightsubstrlengthcharindex-a209089 . There are examples to better understand ;-) It will work on MS and other sql servers normally ;-)
The only db independent solution I see is to get the number of days between today and Jan 1 of curr. year. Then divide it by 7 and round it up. There is 73 days from Jan 1 till today, which gives 10.43 as week number. The ISO week number is 11.
Correction: the number of days between last day of the current week and Jan 1 of curr. year. In this case the ISO week is 10, and 68/7 = 10 (rounded).
The best idea I found is
SELECT ROUND(((DAY(NOW())-1)/7)+1)
select (DATEPART(yyyy , CAST(GETDATE() AS datetime)) * 100 +
DATEPART(ww , CAST(GETDATE() AS datetime))) as week