Calculating Date ranges in T-SQL - tsql

I have a date field that I would like to results returned where the date is minus a given amount of days. For example, WHERE #today - 30 would give me the last 30 days of data. How can I do this?

For calculating date ranges you can use:-
WHERE date_column BETWEEN date1 AND date2
Now for subtracting you can use:-
DATEADD(DAY, -30, '9/1/2011')
something like:=
WHERE datecolumn BETWEEN dateAdd(day,-30,date1) AND date2

You can use dateAdd. The syntax of day may vary based on your DBMS
WHERE datecolumn BETWEEN dateAdd(day,-30,getDate()) AND getDate()
or
WHERE datecolumn > dateAdd(day,-30,getDate())

Related

How to truncate a date to the beginning of week (Sunday)?

I need to truncate dates to the start of week, which is Sunday in my case. How can I do this in PostgreSQL? This truncates to Monday:
date_trunc('week', mydate)
If you subtract the dow value (0 for Sundays, 6 for Saturdays) from the current date than you get the previous Sunday which is the begin of your Sunday-based week
demo:db<>fiddle
SELECT
my_date - date_part('dow', my_date)::int
FROM
my_table
Further reading, documentation
You could truncate the date to the week's Monday, then subtract 1 day, e.g:
SELECT (date_trunc('week', now() + interval '1 day') - interval '1 day')::DATE;
date
------------
2019-06-16
As per documentation, date_trunc() accepts values of type date and timestamp and returns a timestamp (thus the cast at the end).

DB2 get max date of four dates query

I want to get greater date from four date columns and fields can be NULL.
Please help me to write a query for this.
Example:
select max(date1, date2, date3, date4) from table A where tag_id='xxxxx'
You can work with unions which combine your query results and then get the max date of the combined columns
Here is the same question asked in another post
Hope that helps you
select max(max_date) from
(select date1 max_date from table A where tag_id='xxxxx'
union all
select date2 from table A where tag_id='xxxxx'
union all
select date3 from table A where tag_id='xxxxx'
union all
select date4 from table A where tag_id='xxxxx')
Here you have:
SELECT
CASE
WHEN date1 >= date2 AND date1 >= date3 THEN date1
WHEN date2 >= date1 AND date2 >= date3 THEN date2
WHEN date3 >= date1 AND date3 >= date2 THEN date3
ELSE date1
END AS RecentDate
FROM table A
WHERE A.tag_id='xxxxx'
Hope it helps,
Did you try your example query?
MAX() (and MIN() for that matter) are a bit unusual....they exists as both an aggregate function operating on multiple rows and a scalar function operating on multiple columns.
The works fine for me on DB2 for IBM i:
select max(dte1,dte2,dte3,dte4) from qtemp.test

T-SQL change Time Portion of a DateTime, using another DateTime Time portion

I have a select statement that returns the following:
SELECT
StartDate
,EndDate
FROM
MyTable
And the result returns the following data:
What I want is change the time portion of StartDate using the value from EndDate. So that only the time portion of both dates is the same, taken from EndDate. I have to keep identical, down to milliseconds.
Is it possible using DATEADD function?
Using DateAdd and DateDiff:
SELECT DATEADD(DAY, DATEDIFF(DAY, EndDate, startDate), EndDate) As StartDate,
EndDate
FROM MyTable
I'm adding the days difference between the start date and the end date.
Since the DateDiff have the later date before the earlier date, it returns the days difference as a negative number.
Another option that I'm guessing some people will find more readable is this:
SELECT DATEADD(DAY, -DATEDIFF(DAY, startDate, EndDate), EndDate) As StartDate,
EndDate
FROM MyTable

count data in current month - not 30 days back Postgres statment

Ive this query which return data for 30 days from current date , need to modify it to return data for current month only not 30 days from current date
SELECT count(1) AS counter FROM users.logged WHERE createddate >=
date_trunc('month', CURRENT_DATE);
any tips how to tweak this query , at based on Postgres
regards
Something like this should work.
SELECT count(1) AS counter
FROM users.logged
WHERE date_trunc('month', createddate) = date_trunc('month', current_date);
It is already supposed to return the values in current month. Truncation does the conversion 10 Nov 2013 14:16 -> 01 Nov 2013 00:00 and it will return the data since the beginning of this month. The problem seems to be something else.
Ive this query which return data for 30 days from current date , need to modify it to return data for current month only not 30 days from current date
That's incorrect. Your query:
SELECT count(1) AS counter FROM users.logged WHERE createddate >= date_trunc('month', CURRENT_DATE);
returns all dates >= Nov 1st 00:00:00, in other words what you say that you want already. Or then, you've simplified your query and left out the more important bits — those that are broken. If not:
It might be that you've dates in the future and that you're getting incorrect counts as a result. If so, add an additional criteria in the where clause:
AND created_date < date_trunc('month', CURRENT_DATE) + interval '1 month'
It might also be that your sample data has a bizarre row with a time zone such that it looks like the timestamp is from this month but the date/time arithmetics land it last month.
This is will give you data for the current month only. I try to extract month and year. The last step is you can compare created date against current date-time.
SELECT count(1) AS counter
FROM users.logged
WHERE
EXTRACT(MONTH FROM createddate) = EXTRACT(MONTH FROM current_date)
AND EXTRACT(YEAR FROM createddate) = EXTRACT(YEAR FROM current_date);

T-sql Monday before date

I work at a college and our student management systems academic year start date is determined by the Monday on or before the 1st of August. I need to match this in my query, is there a way to easily get the date of the Monday on or before this date.
The accepted answer didn't work for me because I needed both a Sunday week and a Monday week in the same query. This works across different "datefirst" settings:
SELECT DATEADD(d, -((DATEPART(WEEKDAY, '20110515') - DATEPART(dw, '19000101') + 7) % 7), '20110515')
"DATEPART(dw, '19000101')" will determine your "datefirst" setting since 1900-01-01 was on a Monday. If you want a Tuesday based week, you can change 19000101 to 19000102.
BTW, '20110515' is the only date format that works across all SQL Server culture settings. Dates like '2011-05-06' will get mis-interpreted in certain countries. (credit to Itzik Ben-Gan for pointing this out)
set datefirst 1; -- Make Monday the first day of the week
select dateadd(dd, -1*(datepart(dw, '2009-08-01')-1), '2009-08-01')
Returns July 27th, 2009, which is the Monday on or before August 1. Change it to 2005 when Aug 1 was a Monday and the query will return 08-01
You could use datepart to get the weekday, and then do a little math to back into your monday. This example is using the US default of datefirst 7 (in which Monday is day 2 of the week). Adjust the days to add to be which day of the week Monday is for your locale.
select dateadd(dd, -datepart(dw, '2009-08-01') + 2, '2009-08-01')
very hacky
DECLARE #weekday int
SELECT #weekday = DATEPART(WEEKDAY, '1-Aug-2009')
SELECT CASE
WHEN #weekday = 1 THEN '1-Aug-2009' ELSE DATEADD ( dd,(#weekday-2)*-1, '1-Aug-2009')
END
This is a generic algorithm that will return the first Monday of any month (#inputdate):
DATEADD(wk, DATEDIFF(wk, 0, dateadd(dd, 6 - datepart(day, #inputDate), #inputDate)), 0)
It is a common method for getting the first monday of the month in SQL Server. This link explains how the above calculation works along with many other date calculations.
Here is how the above algorithm could be used to get the Monday on or before the 1st day of a month:
-- Set month to get Monday before or at 1st of month.
DECLARE #inputDate DATETIME
SET #inputDate = '2009-08-01'
-- Get first Monday of month.
DECLARE #firstMonday DATETIME
SET #firstMonday = DATEADD(wk, DATEDIFF(wk, 0, dateadd(dd, 6 - datepart(day, #inputDate), #inputDate)), 0)
-- Determine date for first Monday on or before 1st of month.
DECLARE #startDate DATETIME
SET #startDate = #firstMonday
IF #firstMonday > #inputDate
SET #startDate = DATEADD(wk, -1, #firstMonday)
SELECT #startDate