sql- move each date to 1st day of the month - sql

I need to take every date to the first day of the month. For example if I have:
20140103 I need to have 20140101
I thought a good idea could be loaddate - difference between loaddate and 1st date and I wrote:
loaddate- DATEdiff(day, day(loaddate),loaddate)
But the result is wrong. How can I solve this???
Thanks

For SQL Server You can do:
SELECT CONVERT(VARCHAR(25),DATEADD(dd,-(DAY(loaddate)-1),loaddate),101)
For:
SELECT CONVERT(VARCHAR(25),DATEADD(dd,-(DAY(GETDATE())-1),GetDATE()),101)
You will get back: 09/01/2014

Related

How to add/subtract weeks to the third day of the week?

I'm trying to figure out how to translate this line of PROC SQL code into Snowflake SQL but haven't found a way yet.
%LET last_post_dt = %SYSFUNC(INTNX(WEEK.3,%SYSFUNC(TODAY(),),-2,B),DATE9.);
Basically, its subtracting 2 weeks from the third day of the current week (monday = 1).
I've tried altering the session by using WEEK_START and other functions such as DATEADD, but haven't been able to solve this.
Thanks in advance!
You can use date_trun() to get whatever today is to a Monday. Then add 2 for 3rd day of the week, and then subtract 2 weeks from that.
SELECT DATE_TRUNC('week',current_date()) as week_start,
DATEADD('day',2,week_start) as week_3rd_day,
DATEADD('week',-2,week_3rd_day) as weeks_ago,
DATEADD('week',-2,DATEADD('day',2,DATE_TRUNC('week',current_date()))) as all_in_one_line_date

Determine date gaps

I have a SQL Server table that has a begin date and end date column that denote the beginning and ending range of a pricing schedule.
As the years go by, many versions of this same schedule will be created, with different beginning and ending dates.
What I would like to do is ensure that the user doesn't add, or, in some cases edit, a beginning or ending date in such a way that days would be excluded in the overall time frame.
So if the data looked like this:
Start | End
-----------+--------------
01/01/2015 | 06/30/2015
07/01/2015 | 09/30/2016
10/01/2016 | 12/31/2020
So, lets assume I attempted to revised the last row Start to 10/15/2016. That would create a gap of days between 10/01/2016 and 10/14/2016, but I have no idea who to write a script to do this for me. Ultimately, I would like a list of all missing dates, but even a count of days missing would be great.
Is this possible or am I approaching the issue incorrectly? Any ideas?
Using SQL Server 2012, if it matters.
I am guessing you don't want overlaps either. So, just use lag() and check that it is the date before:
select t.*
from (select t.*,
lag(end_date) over (order by start_date) as prev_end_date
from t
) t
where start_date <> dateadd(day, 1, prev_end_date)

Oracle SQL: Dynamic timeframe calculation

Greetings all knowing Stack.
I am in a bit of a pickle, and I am hoping for some friendly assistance form the hive mind.
I need to write a query that returns the difference in days between a registration date (stored in a table column) and the first day of the last September.
For example; assuming the query was being run today (24-10-2016) for a record with a registration date of 14-07-2010, I would want the script to return the difference in days between 14-07-2010 and 01-09-2016
However had I run the same query before the end of last August, for example on 12-08-2016, I would want the script to return the difference in days between 14-07-2010 and 01-09-2015.
I'm fine with the process of calculating differences between dates, it's just the process of getting the query to return the 'first day of the last September' into the calculation that is tripping me up!
Any input provided would be much appreciated.
Thankyou =)
Try this approach:
add four months to the current date
truncate this date to the first of year
subtract four months again
Add_Months(Trunc(Add_Months(SYSDATE, 4), 'year'), -4)
Hope this might help.
WITH T AS (SELECT TO_DATE('14-07-2010','DD-MM-YYYY') REG_DATE,
SYSDATE EXEC_DATE
FROM DUAL)
SELECT CASE WHEN TO_CHAR(EXEC_DATE,'MM') >= 9
THEN ADD_MONTHS(TRUNC(EXEC_DATE,'YEAR'),8)
ELSE ADD_MONTHS(TRUNC(ADD_MONTHS(EXEC_DATE,-12),'YEAR'),8)
END
- REG_DATE AS DIFF
FROM T;

SQL - How do i get back the result between the 2014-02-20 and 2014-03-20 then for 04,05 etc

I have this SQL at the moment:
SELECT *
FROM courtesy
WHERE DATE
BETWEEN '2014-02-20 00:00:00'
AND '2014-03-20 00:00:00'
how would i get it to automatically get results between the 20th and the 20th of every month when the month changes?
Thanks
***Edit: i meant between the 20th of feb and the 20th of mar. Thanks.
Please try:
SELECT *
FROM courtesy
WHERE day(DATE)=20
If I understand you correctly, this will do it.
SELECT *
FROM courtesy
WHERE DAY(DATE) = 20
I think the easiest way is to subtract 19 days and check for the current month. If I understand your question correctly, here is one way:
SELECT *
FROM courtesy
WHERE year(DATE - 19) = year(getdate()) and
month(DATE - 19) = month(getdate())
Note: this assumes that date is really stored as a datetime (because you are comparing it to a constant with a time component). You can also use datediff().
I also assume that you don't really mean between, because that would count the 20th twice, once in each month.

Add date without exceeding a month

I hope someone could help me on this.
I want to add a month to a database date, but I want to prevent two jumping over month on those days at the end.
For instance I may have:
Jan 31 2009
And I want to get
Feb 28 2009
and not
March 2 2009
Next date would be
March 28 2009
Jun 28 2009
etc.
Is there a function that already perform this kind of operation in oracle?
EDIT
Yeap. I want to copy each month all the records with some status to the next ( so the user don't have to enter again 2,000 rows each month )
I can fetch all the records and update the date manually ( well in an imperative way ) but I would rather let the SQL do the job.
Something like:
insert into the_table
select f1,f2,f3, f_date + 30 /* sort of ... :S */ from the_Table where date > ?
But the problem comes with the last day.
Any idea before I have to code something like this?
for each record in
createObject( record )
object.date + date blabala
if( date > 29 and if februrary and the moon and the stars etc etc 9
end
update.... et
EDIT:2
Add months did the trick.
now I just have this:
insert into my_table
select f1, add_months( f2, 1 ) from my_table where status = etc etc
Thanks for the help.
Oracle has a built-in function ADD_MONTHS that does exactly that:
SQL> select add_months(date '2008-01-31',1) from dual;
ADD_MONTHS(
-----------
29-FEB-2008
SQL> select add_months(date '2008-02-29',1) from dual;
ADD_MONTHS(
-----------
31-MAR-2008
I think you're looking for LAST_DAY:
http://download.oracle.com/docs/cd/B28359_01/olap.111/b28126/dml_functions_2006.htm
I just did:
select add_months(TO_DATE('30-DEC-08'), 2) from dual
and got
28-FEB-2009
No need to use LAST_DAY. If you went that route, you could create a function that:
1. takes a date
2. Changes the day to the first of the month.
3. Add a month.
4. Changes the day to the LAST_DAY for that month.
I think you'll have to write it on your own, My advice is first to evaluate the "last day of the month" with this method:
Add one month (not 30 days, one month!)
Find first day of the month (should be easy)
substract one day
Then compare it to your "plus x days" value, and choose the lowest one (I understood the logic behind the jump from 31/Jan to 28/Feb, but I don't get it for the jump from 28-Feb to 28-Mar)
It sounds like you want the current month plus one (with appropriate rollover in December)
and the minimum of the last day of that month and the current day.