T-SQL Date Function - tsql

I have a T-SQL script that runs every weekday. The script does a lookup for new customers in the past 24 hours, with the exceptionof Monday it will do a lookup in the past 72 hours (Friday through Sunday)
Select FirstName, LastName, CustomerID, Date
FROM Customers
WHERE
(
(
DATEPART(WEEKDAY, GetDate())=2 AND
DATEDIFF(DAY, Customers.Date, GetDate()) <= 3 AND
DATEDIFF(DAY, Customers.Date, GetDate()) >= 1
)
OR DATEDIFF(DAY, Customers.Date, GetDate()) = 1
)
I need to change this to do a lookup 30 days prior instead.
ANy ideas? Thanks.

WHERE DATEDIFF(DAY, Customers.Date, GetDate()) <= 30

Related

T-SQL Retrieve Last 6 Weeks Data to the Previous Saturday

SELECT TOP 100 *
FROM FactSalesDetail
WHERE TradingDate >= DATEADD(ww, -6, (Select MAX([TradingDate]) From FactSalesDetail))
ORDER BY TradingDate
Can anyone advise how I can convert the above WHERE Clause from retrieving the last 6 weeks data from Max Date in my Fact Table to the last 6 weeks to the Previous Saturday?
So as of Today that would Saturday 1st Jan and then back 6 weeks from that?
Using the current weekday can get you last Saturday.
And if you bring ##DATEFIRST into the equation then it won't depend on the DATEFIRST setting.
SELECT TOP 100 *
FROM FactSalesDetail
WHERE TradingDate >= CONVERT(DATE, DATEADD(WEEK, -6, DATEADD(DAY, -(##DATEFIRST+DATEPART(WEEKDAY,GETDATE()))%7,
GETDATE())))
AND TradingDate <= CONVERT(DATE, DATEADD(DAY, -(##DATEFIRST+DATEPART(WEEKDAY,GETDATE()))%7,
GETDATE()))
ORDER BY TradingDate
Test snippet for date range
SET DATEFIRST 7;
SELECT
datename(weekday, date_now) AS weekday_now, date_now
, datename(weekday, date1) AS wd1, date1
, datename(weekday, date2) AS wd2, date2
FROM
(
SELECT
CAST(GETDATE() AS DATE) AS date_now
, CONVERT(DATE, DATEADD(WEEK, -6, DATEADD(DAY, -(##DATEFIRST+DATEPART(WEEKDAY,GETDATE()))%7,
GETDATE()))) AS date1
, CONVERT(DATE, DATEADD(DAY, -(##DATEFIRST+DATEPART(WEEKDAY,GETDATE()))%7,
GETDATE())) AS date2
) q
weekday_now
date_now
wd1
date1
wd2
date2
Tuesday
2022-01-04
Saturday
2021-11-20
Saturday
2022-01-01
db<>fiddle here

Select all rows 7 days prior from a specific date

I want to get all rows 7 days prior from 01/09/2017
I know I can do
Load_DTM <= '2017-01-09' and Load_DTM >= '2017-01-02'
But can I not use DateAdd or DatePart?
i.e. DateAdd(dd, -7, '2017-01-09')
Load_DTM BETWEEN DATEADD(dd,-7,'2017-01-09') AND '2017-01-09 11:59:59'
ought to work.
You should be able to do exactly what you showed in your example:
SELECT * FROM Table WHERE DateField = DATEADD(DAY, -7, '2017-09-01')
Since running:
SELECT DATEADD(DAY, -1, GETDATE())
Gives you:
2017-03-15 19:26:29.833

Number of entries between dates

I have a table with the following structure: -
day, id
2016-03-13, 123
2016-03-13, 123
2016-03-13, 231
2016-03-14, 231
2016-03-14, 231
2016-03-15, 129
And I'd like to build a table that looks like: -
id, d1, d7, d14
123, 1, 1, 1
231, 1, 2, 2
129, 1, 1, 1
Essentially for a given id, list the number of days which have an entry within a time window. So if id 123 has 10 entries within the last 14 days - d14 would be 10.
So far I have: -
SELECT
day,
id
FROM
events
WHERE
datediff (DAY, day, getdate()) <= 7
GROUP BY
day,
id
This query will do:
SELECT
id,
COUNT(DISTINCT CASE WHEN current_date - day <= 1 THEN 1 END) d1,
COUNT(DISTINCT CASE WHEN current_date - day <= 7 THEN 1 END) d7,
COUNT(DISTINCT CASE WHEN current_date - day <= 14 THEN 1 END) d14
FROM
events
GROUP BY
id
ORDER BY
id
Or, since PostgreSQL 9.4, slightly more concise:
SELECT
id,
COUNT(DISTINCT day) FILTER (WHERE current_date - day <= 1) d1,
COUNT(DISTINCT day) FILTER (WHERE current_date - day <= 7) d7,
COUNT(DISTINCT day) FILTER (WHERE current_date - day <= 14) d14
FROM
events
GROUP BY
id
ORDER BY
id
try this:
SELECT id
, count(case when DAY = getdate() then 1 else null end) as d1
, count(case when DAY + 7 >= getdate() then 1 else null end) as d7
, count(case when DAY + 14 >= getdate() then 1 else null end) as d14
FROM events
WHERE DAY between DAY >= getdate() - 14
--or if you can have day > today ... and DAY between getdate() - 14 and getdate()
GROUP By id

IIF Conditional StartDate EndDate int/date collision

I am trying to use the IIF statements in SS-2012
I have this which works fine
SELECT
NULLIF(IIF( a.EndDate is null
, DATEDIFF(MONTH, a.StartDate, getdate()) ,
IIF( a.EndDate is not null
, DATEDIFF(MONTH, a.StartDate, a.EndDate) , '')),'')
AS Months
,NULLIF(IIF( a.EndDate is null
, DATEDIFF(Day, a.StartDate, getdate()) ,
IIF( a.EndDate is not null
, DATEDIFF(Day, a.StartDate, a.EndDate) , '')),'')
AS DateDays
FROM
TableDates a
The problem I came across is if the start date and enddate are on the same date(I am trying to default it to 1 month and 30 or 31 days whatever month it is)
I am gettiing
int is incompatible with date
When trying this below
,NULLIF(
IIF ( (a.EndDate is null) , DATEDIFF(Day, a.StartDate, getdate()) ,
IIF ( (a.StartDate = a.EndDate)
, DATEADD(Day, DATEDIFF(Day, a.StartDate, a.EndDate), a.EndDate),
IIF ( (a.EndDate is not null) , DATEDIFF(Day, a.StartDate, a.EndDate),'')
)),'')
How can I default the days to 30-31 and month to 1 if the dates are the same?
If you need to show the number of days of the month as default where start date and enddate are on the same date then i hope the below query will work for you
IIF ( (a.StartDate = a.EndDate),
(datediff(day, a.StartDate, dateadd(month, 1, a.StartDate))),...
and to show the month as default where start date and enddate are on the same date
IIF ( (a.StartDate = a.EndDate),Month(a.StartDate),...

Get First and Last Day of Any Year

I'm currently trying to get the first and last day of any year. I have data from 1950 and I want to get the first day of the year in the dataset to the last day of the year in the dataset (note that the last day of the year might not be December 31rst and same with the first day of the year).
Initially I thought I could use a CTE and call DATEPART with the day of the year selection, but this wouldn't partition appropriately. I also tried a CTE self-join, but since the last day or first day of the year might be different, this also yields inaccurate results.
For instance, using the below actually generates some MINs in the MAX and vice versa, though in theory it should only grab the MAX date for the year and the MIN date for the year:
;WITH CT AS(
SELECT Points
, Date
, DATEPART(DY,Date) DA
FROM Table
WHERE DATEPART(DY,Date) BETWEEN 363 AND 366
OR DATEPART(DY,Date) BETWEEN 1 AND 3
)
SELECT MIN(c.Date) MinYear
, MAX(c.Date) MaxYear
FROM CT c
GROUP BY YEAR(c.Date)
You want something like this for the first day of the year:
dateadd(year, datediff(year,0, c.Date), 0)
and this for the last day of the year:
--first day of next year -1
dateadd(day, -1, dateadd(year, datediff(year,0, c.Date) + 1, 0)
try this
for getting first day ,last day of the year && firstofthe next_year
SELECT
DATEADD(yy, DATEDIFF(yy,0,getdate()), 0) AS Start_Of_Year,
dateadd(yy, datediff(yy,-1, getdate()), -1) AS Last_Day_Of_Year,
DATEADD(yy, DATEDIFF(yy,0,getdate()) + 1, 0) AS FirstOf_the_NextYear
so putting this in your query
;WITH CT AS(
SELECT Points
, Date
, DATEPART(DY,Date) DA
FROM Table
WHERE DATEPART(DY,Date) BETWEEN
DATEPART(day,DATEADD(yy, DATEDIFF(yy,0,getdate()), 0)) AND
DATEPART(day,dateadd(yy, datediff(yy,-1, getdate()), -1))
)
SELECT MIN(c.Date) MinYear
, MAX(c.Date) MaxYear
FROM CT c
GROUP BY YEAR(c.Date)
I should refrain from developing in the evenings because I solved it, and it's actually quite simple:
SELECT MIN(Date)
, MAX(Date)
FROM Table
GROUP BY YEAR(Date)
I can put these values into a CTE and then JOIN on the dates and get what I need:
;WITH CT AS(
SELECT MIN(Date) Mi
, MAX(Date) Ma
FROM Table
GROUP BY YEAR(Date)
)
SELECT c.Mi
, m.Points
, c.Ma
, f.Points
FROM CT c
INNER JOIN Table m ON c.Mi = m.Date
INNER JOIN Table f ON c.Ma = f.Date