I have a query pulling dates from field [DATE] BETWEEN '10/1/2017' AND '10/31/2017'
I want to add days to the the end date in the between criteria (10/31/2017). It seems impossible. I can add months perfectly using ADD_MONTHS, but there doesn't seem to be a function ADD_DAYS.
Your help is greatly appreciated!
add_months deals with the special cases that arise from having variable length months.
For other intervals of time, things are much simpler:
To add 5 days to the current day, use this:
SYSTEM.ADMIN(ADMIN)=> select current_date, current_date + interval '5 days';
DATE | ?COLUMN?
------------+---------------------
2017-12-19 | 2017-12-24 00:00:00
(1 row)
T2DB.ADMIN(ADMIN)=> select * from interval_test where col1 between (current_timestamp - interval '2 days') and (current_timestamp + interval '3 days');
COL1
------------
2017-12-19
(1 row)
Related
I have a table with date like that:
OBJECT TIMESTAMP_START TIMESTAMP_END
House 2020-02-20 09:33:24 2020-02-20 09:33:33
Dog 2020-02-20 18:00:03 2020-02-21 18:33:22
Cat 2020-02-11 19:00:00 2020-02-11 19:15:23
I need to extract all objects,start timestamp and end timestamp whose timestamp start is between (18:00 hours and 09:00)
In that case was Dog and Cat
How could I make that in postgreSql ? Do you think is possible easily?
Thanks!
Since you exclude both bounds, a rare case where BETWEEN is correct:
select *
from tbl
where timestamp_start::time NOT BETWEEN time '09:00' AND time '18:00';
You cannot do this with TIME alone because in hours 09:00 is always less than 18:00, and from 09:00 to 18:00 is the time to be excluded. You can get this by truncating to the start and adding the appropriate interval.
with the_table (object, timestamp_start,timestamp_end ) as
( values ('House', '2020-02-20 09:33:24'::timestamp, '2020-02-20 09:33:33'::timestamp)
, ('Dog', '2020-02-20 18:00:03'::timestamp, '2020-02-21 18:33:22'::timestamp)
, ('Cat', '2020-02-11 19:00:00'::timestamp, '2020-02-11 19:15:23'::timestamp)
, ('Mouse', '2020-02-11 20:00:00'::timestamp, '2020-02-12 08:00:00'::timestamp)
)
select *
from the_table
where timestamp_start between
date_trunc('day', timestamp_start) + interval '18 hours' and
date_trunc('day', timestamp_start) + interval '1 day 9 hours' ;
Of course this get all such rows matching the times even if they are years old. You might want to consider that as well. Just a suggestion.
You can cast the timestamp to time
select *
from the_table
where timestamp_start::time > time '18:00'
and timestamp_start::time < time '09:00'
I have a table named TimeList:
| Slot |
==============
| 10:00 |
| 11:00 |
| 12:00 |
| 13:00 | and so on
That saves the Times in Varchar(5)
The desired result should be showing the rows with time that is more than the current time, for example if the current time is 11:12 A.M. the result should return:
| Slot |
==============
| 12:00 |
| 13:00 |
I tried to Convert the two values into time and comparing them with:
SELECT *
FROM TimeList
WHERE Convert(Time, Slot) > Convert(Time, GETDATE())
But it didn't work saying that Time is not a recognizable format in SQL
Is there anyway I could compare the two time slots?
Depends on the version of SQL Server you're running, I think. There is a CAST(.. as time) in 2012 or later, but I think that's a fairly new development. So... to compare the current date/time with the Timelist where the times are converted to "time, if it were today," something like this should work :
SELECT *
FROM TimeList
WHERE Convert(Datetime, FORMAT (GETDATE(), 'd') + ' ' + Slot) > GETDATE()
Conversely, if you want to compare the times to the current time, as text:
SELECT *
FROM TimeList
WHERE Slot > FORMAT(GETDATE(), N'hh\:mm')
Try This.....
SELECT *
FROM TimeList
WHERE Slot > CONVERT(time,GETDATE())
Thank you very much for all the answers, fortunately I found the answer to my question inspired by your answers.
The solution is:
SELECT *
FROM TimeList
WHERE Slot > CONVERT(varchar(5),GETDATE(), 108)
Where it seems that 108 is the format for time saved as char/varchar in which Slot was categorized as too
Im trying to go to a particular date after finding a "start date"
Eg. I have the column start_date "01-OCT-2014" but now after getting the year "2014" from this data I want to create a column called "fin_yr" which should add +1 to the year and show the date "01-Jul-2015"
another eg:
start_date "23-APR-2013" then a new column called "fin_yr" should have the value "01-Jul-2014"
thanks a ton (Netezza answers please)
The following will work in a Netezza environment, using the extract function ( date_part would have worked just as well) to add one to the year, and set the month and day to July 1st.
SELECT start_date,
to_date(extract(YEAR FROM start_date) +1 || '0701', 'YYYYMMDD') fin_year
FROM (
SELECT CURRENT_DATE start_date
)
foo;
START_DATE | FIN_YEAR
------------+------------
2015-04-28 | 2016-07-01
(1 row)
if you column name is "dt" then you can add 1 year by doing this:
SELECT DATEADD(year, 1, dt)
FROM foo
I don't understand how you go from 23-APR-2013 to 01-Jul-2014 though. That's adding 1 year + some number of days. If for example you want to add 1 year + 99 days you could do something like:
SELECT DATEADD(day, 99, DATEADD(year, 1, dt))
FROM foo
I am creating a query to give number of days between two days based on year. Actually I have below type of date range
From Date: TO_DATE('01-Jun-2011','dd-MM-yyyy')
To Date: TO_DATE('31-Dec-2013','dd-MM-yyyy')
My Result should be:
Year Number of day
------------------------------
2011 XXX
2012 XXX
2013 XXX
I've tried below query
WITH all_dates AS
(SELECT start_date + LEVEL - 1 AS a_date
FROM
(SELECT TO_DATE ('21/03/2011', 'DD/MM/YYYY') AS start_date ,
TO_DATE ('25/06/2013', 'DD/MM/YYYY') AS end_date
FROM dual
)
CONNECT BY LEVEL <= end_date + 1 - start_date
)
SELECT TO_CHAR ( TRUNC (a_date, 'YEAR') , 'YYYY' ) AS YEAR,
COUNT (*) AS num_days
FROM all_dates
WHERE a_date - TRUNC (a_date, 'IW') < 7
GROUP BY TRUNC (a_date, 'YEAR')
ORDER BY TRUNC (a_date, 'YEAR') ;
I got exact output
Year Number of day
------------------------------
2011 286
2012 366
2013 176
My question is if i use connect by then query execution takes long time as i have millions of records in table and hence i don't want to use connect by clause
connect by clause is creating virtual rows against the particular record.
Any help or suggestion would be greatly appreciated.
From your vague expected results I think you want the number of records between those dates, not the number of days; but it's rather unclear. Since you refer to a table in the question I assume you want something related to the table data, not simply days between two dates which wouldn't depend on a table at all. (I have no idea what the connect by clause reference means though). This should give you that, if it is what you want:
select extract(year from date_field), count(*)
from t42
where date_field >= to_date('01-Jun-2011', 'DD-MON-YYYY')
and date_field < to_date('31-Dec-2013') + interval '1' day
group by extract(year from date_field)
order by extract(year from date_field);
The where clause is as you'd expect between two dates; I've assumed there might be times in your date field (i.e. not all at midnight) and that you want to count all records on the last date in your range. Then it's grouping and counting based on the year for each record.
SQL Fiddle.
If you want the number of days that have records within the range, then you can just vary the count slightly:
select extract(year from date_field), count(distinct trunc(date_field))
...
SQL Fiddle.
you can use the below function to reduce the number of virtual rows by considering only the years in between.You can check the SQLFIDDLE to check the performance.
First consider only the number of days between start date and the year end of that year or
End date if it is in same year
Then consider the years in between from next year of start date to the year before the end date year
Finally consider the number of days from start of end date year to end date
Hence instead of iterating for all the days between start date and end date we need to iterate only the years
WITH all_dates AS
(SELECT (TO_CHAR(START_DATE,'yyyy') + LEVEL - 1) YEARS_BETWEEN,start_date,end_date
FROM
(SELECT TO_DATE ('21/03/2011', 'DD/MM/YYYY') AS start_date ,
TO_DATE ('25/06/2013', 'DD/MM/YYYY') AS end_date
FROM dual
)
CONNECT BY LEVEL <= (TO_CHAR(end_date,'yyyy')) - (TO_CHAR(start_date,'yyyy')-1)
)
SELECT DECODE(TO_CHAR(END_DATE,'yyyy'),YEARS_BETWEEN,END_DATE
,to_date('31-12-'||years_between,'dd-mm-yyyy'))
- DECODE(TO_CHAR(START_DATE,'yyyy'),YEARS_BETWEEN,START_DATE
,to_date('01-01-'||years_between,'dd-mm-yyyy'))+1,years_between
FROM ALL_DATES;
In Oracle you can perform Addition and Substraction to dates like this...
SELECT
TO_DATE('31-Dec-2013','dd-MM-yyyy') - TO_DATE('01-Jun-2011','dd-MM-yyyy')
DAYS FROM DUAL;
it will return day difference between two dates....
select to_date(2011, 'yyyy'), to_date(2012, 'yyyy'), to_date(2013, 'yyyy')
from dual;
TO_DATE(2011,'Y TO_DATE(2012,'Y TO_DATE(2013,'Y
--------------- --------------- ---------------
01-MAY-11 01-MAY-12 01-MAY-13
select to_char(date_field,'yyyy'), count(*)
from your_table
where date_field between to_date('01-Jun-2011', 'DD-MON-YYYY')
and to_date('31-Dec-2013 23:59:59', 'DD-MON-YYYY hh24:mi:ss')
group by to_char(date_field,'yyyy')
order by to_char(date_field,'yyyy');
Original Question
I need to write a Microsoft SQL statement where I subtract a date from number of days from another table. So, essentially, the table example is below:
Table 1 (date) Table 2 (number of days)
2013-05-08 23:59:13.000 7
2013-05-08 23:59:16.000 7
2013-05-08 23:59:06.000 7
Any help would be appreciated.
Updated Question
The only two item I have to work with is the following information:
I need to know how long an invoice has been in the invoice queue. TimeoutDate is when the invoice will timeout of the queue, and TimeOutDays is the length of days this queue is given before it times out, but it's business days, so excluding weekends.
So, if you calculate based on this information, the invoice has been in the queue for 8 business days <-- this is the answer I need to get from the query.
Extra Information
The invoice entered into the system 04/30/2013, but since the webapp does not count the day the invoice entered the system, the time-out counter starts the day after, which is 05/1/2013. Hope this explains a little clearer!
I have a quick query, but that's not going to help, since it doesn't show what I need, but in effect below is the results of what I need:
Try
SELECT DATEADD(day, -(t2.days), t1.datefield) new_date
FROM table1 t1 JOIN
table2 t2 ON t1.id = t2.id
Output:
| NEW_DATE |
------------------------------
| May, 01 2013 23:59:13+0000 |
| May, 01 2013 23:59:16+0000 |
| May, 01 2013 23:59:06+0000 |
SQLFiddle
UPDATE: A solution to the completely changed question
SELECT timeoutdate,
timeoutdays,
timeoutdays
-((DATEDIFF(dd, GETDATE(), timeoutdate) + 1)
-(DATEDIFF(wk, GETDATE(), timeoutdate) * 2)
-(CASE WHEN DATENAME(dw, GETDATE()) = 'Sunday' THEN 1 ELSE 0 END)
-(CASE WHEN DATENAME(dw, GETDATE()) = 'Saturday' THEN 1 ELSE 0 END)) daysinqueue
FROM table1
Output:
| TIMEOUTDATE | TIMEOUTDAYS | DAYSINQUEUE |
-------------------------------------------------------
| 2013-05-14 23:59:13.000 | 10 | 9 |
SQLFiddle
Thanks #CMS for a solution for getting number of working days between two dates
You can try something like this
Select DATEADD(month, -(Table2.day) , Table1.date)
FROM Table1 Inner Join Table2
ON Table1.Col=Table2.Col
Of-course you can modified the join as per your structure.