I'm looking for a way to have my sql query change the dates in my query on the 15th of every month so my data pulls have a "rolling 12 months". For example, right now, my query pulls the dates (YYYYQMM) between 2018411 and 2019410. I have it hard coded so it looks like this:
Select *
From Table
WHERE Spend_Period_YYYYQMM >= 2018411 and Spend_Period_YYYYQMM <= 2019410
I would like to have a solution that on Dec 15th it changes the dates to 2018412 and 2019411.
I have a solution to change the dates every month like below but would like the dates to change on the 15th:
Spend_Period_YYYYQMM between to_char(date(current_date - cast('13 month' as interval)),'YYYYQMM')
and to_char(date(current_date - cast('2 month' as interval)),'YYYYQMM')
How should I got about it
We can use some CASE clauses and the EOMONTH function along with GetDate() to get your desired range.
DECLARE #date DATETIME = GETDATE();
select case
when day(#date) <= 14
then EOMONTH(#date, -13)
when day(#date) >= 15
then EOMONTH(#date, -12)
end as RollingYearBegin
,case
when day(#date) <= 14
then EOMONTH(#date, -2)
when day(#date) >= 15
then EOMONTH(#date, -1)
end as RollingYearEnd
into #RollingYear
Then if you need the values formatted in that specific way when you call them, you could either complicate that temp table above a bit more, or just make another little table
Select cast(concat(datepart(yyyy,RollingYearBegin), datepart(q,RollingYearBegin), datepart(MM,RollingYearBegin)) as bigint) as YearBegin
,cast(concat(datepart(yyyy,RollingYearEnd), datepart(q,RollingYearEnd), datepart(MM,RollingYearEnd)) as bigint) as YearEnd
into #YYYYQMM
From #RollingYear
Then, in your query, it would be:
Select *
From Table
WHERE Spend_Period_YYYYQMM BETWEEN (Select YearBegin from #YYYYQMM) AND (Select YearEnd from #YYYYQMM)
Related
I need to ignore data anything that expected within the last 10 days back should be received if not ignore it. I am not sure how to write this in SQL. I have EXPDATE column. I am not sure my statement correct or not.
I believe the logic should be like this
Expected Date + 10 Days < Today`s date?
GETDATE() < DATEADD(DAY, +10, GETDATE()) - I found this online but where can I plug in my ExpectedDate column?
Thanks in advance!!
You can do it either way-
First add 10 days to EXPDATE and compare it with todays date like below.
select * from MyTable Where DATEADD(DAY, 10, EXPDATE) < GETDATE()
The other way, you can substract 10 days from today and compare it with EXPDATE.
select * from MyTable Where DATEADD(DAY, -10, GETDATE()) > EXPDATE
I would prefer 2nd one and would use variable to calculate 10 days back date as it's constant and then use it in where clause like below.
Declare #myDate datetime
SET #myDate = DATEADD(DAY, -10, GETDATE())
select * from MyTable Where #myDate > EXPDATE
I have this simple query that returns previous day's data.
SELECT * FROM mytable
WHERE DATEDIFF(day,CONVERT(datetime,mytable.mydate, 121),GETDATE()) = 1
Using this query becomes an issue on Mondays since the previous day is Sunday but there is no data on Sunday.
So I would like the query to retrieve Friday's data (last activity) on Monday
Any ideas how to do this?
Just a little note about date data type. The date field is of VARCHAR data type.
I inherited the database and has been in use now for over 10 years.
Thanks in advance for your assistance.
How about this?
SELECT TOP 1 WITH TIES t.*
FROM mytable t
WHERE mydate < CAST(getdate() as DATE) -- assume mydate is a date
ORDER BY CAST(mydate as DATE) DESC;
This will get the most recent day's data in the table, for any day where there is data.
EDIT:
Apparently, mydate is stored in a varchar. This is a bad idea, but if you are going to do it, then format 121 is a very good choice. I would modify the above as:
SELECT TOP 1 WITH TIES t.*
FROM mytable t
WHERE mydate < CONVERT(VARCHAR(10), getdate(), 121)
ORDER BY LEFT(mydate, 10) DESC;
Note: this does the comparison of the dates as strings. But that is okay, because the dates are in the format YYYY-MM-DD, which is comparable. If performance is an issue, I would advise a computed column on mydate (to convert to a datetime or date) with an index on the column.
You could try something like this. It asumes sunday at the first day of the week.
SELECT * FROM mytable
WHERE DATEDIFF(day,CONVERT(datetime,mytable.mydate, 121),GETDATE()) = case datepart(dw, GETDATE())
when 2 then 3 --read 3 days back on a monday
when 1 then 2 --read 2 days back on a sunday
else 1 end
Declare a datetime variable, and, with DATEPART(), determine which day of the week GETDATE() is (which day the query is being run). Then, on Mondays, change our date by negative two days.
declare #queryDate datetime;
set #queryDate = case when DATEPART(dw, GETDATE()) = 1 then DATEADD(d, -2, GETDATE()) else GETDATE() end;
select * from mytable
where DATEDIFF(day,CONVERT(datetime,mytable.mydate, 121),#queryDate) = 1
i need help on my little problem.
SELECT FORMAT(ServiceDate, 'dd-MM-yyy") AS ServiceDate
FROM Services
WHERE Day(ServiceDate) BETWEEN '1' AND Day(getdate() -2)
AND Month(ServiceDate) =
CASE
WHEN Day(getdate()) <=2
THEN Month(getdate() -1
ELSE Month(getdate())
END
AND Year(ServiceDate) = Year(getdate())
Now the problem is the first and the second of the Month.
The query don't use the last month. It shows the actual month.
I hope its clear what i need.
if we have the 01-06-2016 and i need minus 2, so the query must give me back to the day 30-05-2016
big THX
the output for today with this query
output query
Assuming you are using sql-server, you need to use DATEADD(Day, -2, GETDATE()) for subtracting 2 days from current date.
I think I understand the logic now:
If the current day is the 1st of the month, get all the records from the start of previous month, until 2 days before it ends.
If the current day is the 2nd of the month, get all the records from the start of the previous month until one day before it ends.
If the current day is the 3rd of the month or higher, get all the records from the beginning of the current month until 2 days ago.
Since you are using the FORMAT() function that was introduced in 2012 version, you can also use the EOMONTH() function that was introduced in the same version.
This function returns the date of the end of the month of the date it receives as an argument, and also have a useful optional second argument that specifies the numbers of months to add to the date passed to the function.
Using this function will allow you to write your query without using any functions on the ServiceDate column, thus enabling the use of any indexes defined on this column.
DECLARE #Now datetime = GETDATE()
SELECT FORMAT(ServiceDate, 'dd-MM-yyy') AS ServiceDate
FROM Services
WHERE (
DAY(#Now) <= 2
AND ServiceDate >= DATEADD(DAY, 1, EOMONTH(#Now, -2))
AND ServiceDate < DATEADD(DAY, -(DAY(#Now)-1), EOMONTH(#Now, -1))
)
OR
(
DAY(GETDATE()) > 2
AND ServiceDate >= DATEADD(DAY, 1, EOMONTH(#Now, -1))
AND ServiceDate < DATEADD(DAY, -2, #Now)
)
Compute enddate as 2 days before getdate() and select data in interval from enddate's first of month and enddate.
SELECT FORMAT(ServiceDate, 'dd-MM-yyy") AS ServiceDate
FROM Services
CROSS APPLY (SELECT enddate = DATEADD(D,-2,getdate()) x
WHERE ServiceDate BETWEEN DATEADD(MONTH,DATEDIFF(MONTH,0,x.enddate),0) AND x.enddate
I have a tabel in a relation database which contains a lot of dates.
I my application logic I have divided one day into 4 parts of 6 hours each, starting at: 00:00, 06:00, 12:00 and 18:00.
Now I would like to find the time difference of the earliest record in the database for each quater of a day, and the beginning og the peiod. How can I do that?
In psuedo-sql i guess it looks like
select min(created_at - ROUND_DOWN_TO_6_HOURS(created_at)) from mytabel group by day_quater;
The problem is how to calculate "ROUND_DOWN_TO_6_HOURS". So if "created_at" is 19:15 it will be rounded down to 18:00 and "created_at - ROUND_DOWN_TO_6_HOURS(created_at)" will return 1:15 hourd
I'm working with psql
If you're just trying to locate the records that match these ranges, you could just use that in the WHERE clause like
select * from myTable
where datepart(hh, created_at) between 0 and 6
If your trying to create a computed field that will have the 00 or 06 ... then you could use the "DatePart()" function in sql to pull the hour... DATEPART ( hh, date )... This would return a numeric value of 0, 1, 2, 3, ... 23 and you can compute a field based on this value being between 2 of your hours listed...
Here's a sample...
select
case
when datepart(hh, add_dt) between 0 and 6 then 1
when datepart(hh, add_dt) between 7 and 12 then 2
when datepart(hh, add_dt) between 13 and 18 then 3
when datepart(hh, add_dt) between 19 and 24 then 4
end
from myTable
where add_dt is not null
You could use CASE in conjunction with your date column and datetime functions to establish the quarter-of-day (1,2,3,4) and extract the day part from the datetime value, group by day, quarter, and then use the MIN(yourdatecolumn) to grab the earliest time within each quarter grouping.
Not sure what you mean by "beginning of the period". but you can measure the difference between any arbitrary datetime and your set of earliest times per day-quarter which was instantiated in the manner above.
http://www.postgresql.org/docs/8.2/static/functions-datetime.html
select
record::time - (case
when record::time >= '18:00' then '18:00'
when record::time >= '12:00' then '12:00'
when record::time >= '6:00' then '6:00'
else '0:00' end
)::time as difference
from my_table
My PostgreSQL is a little rusty, but something like this:
select
date_trunc('day',CreatedOn) [Day],
min(case when date_part('hour',TIMESTAMP CreatedOn) < 6 then '00:00'
when date_part('hour',TIMESTAMP CreatedOn) < 12 then '06:00'
when date_part('hour',TIMESTAMP CreatedOn) < 18 then '12:00'
else '18:00'
end) [Quarter]
from MyTable
group by date_trunc('day',CreatedOn)
order by date_trunc('day',CreatedOn)
For example,
the start date = '20100530' and
the end date = '20100602'
How can I write a SQL to display the below result?
month: may, 2 days
month: June, 2 days
Use a recursive CTE to generate all of the dates between the start and end, and then do a simple group and count (caution, not tested, but should be close if not exactly right):
with dates (the_date) as (
select #start_date
UNION ALL
select dateadd(dd, 1, the_date) from dates where the_date <= #end_date
)
select
datepart(mm, the_date) month,
count(*) num_days
from
dates
group by
datepart(mm, the_date)
TBH, you really need to provide more schema and information about the source data. However, given what little we know, you should be able to write:
Select DateName('month', [Date]) As Month
, Cast(DateDiff(d, #StartDate, #EndDate) As varchar(10) - 1) + ' days'
From Table
Where [Date] Between #StartDate And #EndDate
What we'd need to know to refine our solutions is exactly how 2 days is supposed to be calculated. Is it the days between the start and end date? Is it the day of the second parameter?