I have a few dates in the YYYY-MM-DD format in the table column. how can I find the nearest date, less than or equal to today?
Normally I would use:
<= (SELECT TO_CHAR (TRUNC (SYSDATE), 'YYYY-MM-DD') from DUAL)
but it will return all values less or equal, and I only want one, the nearest.
Thanks for help.
One method is:
select t.*
from (select t.*
from t
where datecol < sysdate -- trunc(sysdate) ???
order by datecol desc
) t
where rownum = 1;
Related
I have table as below:
Table Temp:
ID MAX MIN DATE_C
1 34 24 21-APR-17 02.41.38.520000 PM
2 32 26 20-APR-17 02.42.44.569000 PM
I execute the below SQL query to get temperature details on respective date:
SELECT *
FROM Temp t
WHERE t.date_c = TO_DATE( '2017-04-21', 'YYYY-MM-DD')
order by t.id
But it's returning empty records. Whats wrong with my query?
You need to remove the time component on the column. Here is one way:
SELECT *
FROM Temp t
WHERE TRUNC(t.date_c) = DATE '2017-04-21'
ORDER BY t.id;
However, I usually recommend using inequalities, rather than a function on the column:
SELECT *
FROM Temp t
WHERE t.date_c >= DATE '2017-04-21' AND
t.date_c < DATE '2017-04-22'
ORDER BY t.id;
This allows the query to use an index on date_c. I should add that the original version can use an index on (trunc(date_c, id).
21-APR-17 02.41.38.520000 PM is not a DATE; it has a fractional seconds component so it is a TIMESTAMP.
So, if you want to find items that are on a particular day (inputting the TIMESTAMP using an ISO/ANSI timestamp literal):
SELECT *
FROM Temp
WHERE date_c >= TIMESTAMP '2017-04-21 00:00:00' AND
date_c < TIMESTAMP '2017-04-21 00:00:00' + INTERVAL '1' DAY;
or
SELECT *
FROM Temp
WHERE date_c >= TO_TIMESTAMP( :your_date_string, 'YYYY-MM-DD' ) AND
date_c < TO_TIMESTAMP( :your_date_string, 'YYYY-MM-DD' ) + INTERVAL '1' DAY;
it's returning empty records. Whats wrong with my query?
date_c = TO_DATE( '2017-04-21', 'YYYY-MM-DD') matches all rows where the date_c value is exactly 2017-04-21 00:00:00.000000 (including the time component); if you do not have any rows with exactly that date and time then, as you noticed, it will return nothing. If you want to get records matching that day then you need to get values within a range of times between the start and end of the day.
You need to pass date on the column. Here is a way...
SELECT *
FROM Temp t
WHERE CAST(t.CREATED_ON as date)= N'2017-04-22'
ORDER BY t.id
I would like to select 1 if current date falls between 2 dates through Oracle SQL.
I wrote an SQL after reading through other questions.
https://stackoverflow.com/questions/2369222/oracle-date-between-query
https://stackoverflow.com/questions/2399753/select-from-table-by-knowing-only-date-without-time-oracle
But it returned only null. sysdate is the current date that is 01/05/2014 in date format DD/MM/YYYY.
The SQL I wrote is:
select 1 from dual
WHERE to_date(sysdate,'DD/MM/YYYY')
BETWEEN TO_DATE('28/02/2014', 'DD/MM/YYYY')
AND TO_DATE('20/06/2014', 'DD/MM/YYYY');
and
select 1 from dual
WHERE to_date(sysdate,'DD/MM/YYYY') >= TO_DATE('28/02/2014', 'DD/MM/YYYY')
AND to_date(sysdate,'DD/MM/YYYY') < TO_DATE('20/06/2014', 'DD/MM/YYYY');
You don't need to apply to_date() to sysdate. It is already there:
select 1
from dual
WHERE sysdate BETWEEN TO_DATE('28/02/2014', 'DD/MM/YYYY') AND TO_DATE('20/06/2014', 'DD/MM/YYYY');
If you are concerned about the time component on the date, then use trunc():
select 1
from dual
WHERE trunc(sysdate) BETWEEN TO_DATE('28/02/2014', 'DD/MM/YYYY') AND
TO_DATE('20/06/2014', 'DD/MM/YYYY');
SELECT to_char(emp_login_date,'DD-MON-YYYY HH24:MI:SS'),A.*
FROM emp_log A
WHERE emp_login_date BETWEEN to_date(to_char('21-MAY-2015 11:50:14'),'DD-MON-YYYY HH24:MI:SS')
AND
to_date(to_char('22-MAY-2015 17:56:52'),'DD-MON-YYYY HH24:MI:SS')
ORDER BY emp_login_date
TSQL: Dates- need to look for gaps in dates between Two Date
select
distinct
e1.enddate,
e3.startdate,
DATEDIFF(DAY,e1.enddate,e3.startdate)-1 as [Datediff]
from #temp e1
join #temp e3 on e1.enddate < e3.startdate
/* Finds the next start Time */
and e3.startdate = (select min(startdate) from #temp e5
where e5.startdate > e1.enddate)
and not exists (select * /* Eliminates e1 rows if it is overlapped */
from #temp e5
where e5.startdate < e1.enddate and e5.enddate > e1.enddate);
In oracle use below,
select * from table_name where date_column_name between to_date('1-OCT-22') and ('31-OCT-22')
PS: replace table name and date column name and format accordingly
How do I select rows in the past starting from yesterday in Oracle DB where a field like created_date is a timestamp(6)?
I don't want to compare time, just date.
If you want exactly one day prior to the current time:
select *
from table t
where created_date < sysdate - 1;
If you want times before today:
select *
from table t
where created_date <= trunc(sysdate);
From the Oracle documentation on SELECT :
SELECT * FROM orders
WHERE created_date < TO_DATE('2014-04-28', 'YYYY-MM-DD');
I can pass this date format from my application, worked like a charm.
As you want to compare just date:
select *
from table t
where date(created_date) < DATE_SUB(CURRENT_DATE(), INTERVAL 1 DAY);
you can use cast function to deal with timestamp as date:
SELECT cast(SYSTIMESTAMP(6) as date)
FROM dual;
so you can select rows with "yesterdate" date by:
select ....
where cast(SYSTIMESTAMP(6) as date) like sysdate - 1
note: replace SYSTIMESTAMP(6) with column name which has timestamp type.
I have a query which I want to order by year and then month. I have tryed order by to_date( depdate, 'mm' ) and TO_CHAR(depdate, 'YYYY/MM'). Here is an sqlfiddle to the table i am querying and the query itself sqlfiddle
You want to sort by the date value, not by the character string representation. That means that you also want to group by the date value. trunc(<<date column>>, 'mm') truncates a date to midnight on the first of the month. So something like this
SELECT to_char(trunc(DEPDATE,'MM'), 'Mon-YYYY') AS MONTH,
SUM(AMOUNTROOM) AS ROOMTOTAL,
SUM(AMOUNTEXTRAS) AS EXTRATOTAL,
SUM(AMOUNTEXTRAS + AMOUNTROOM) AS OATOTAL
FROM checkins
WHERE checkinstatus = 'D' AND depdate > TO_DATE('2013-12-01', 'yyyy/mm/dd')
AND depdate <= TO_DATE('2014-04-10', 'yyyy/mm/dd')
GROUP BY trunc(depdate,'mm')
ORDER BY trunc(depdate,'mm');
should be what you're looking for. See the updated fiddle
Check out this query. If it is a date field, just plain order by would work for you. You need not use TO_CHAR to convert to string and then sort:
WITH TAB AS
(
SELECT SYSDATE DATEVAL FROM DUAL
UNION
SELECT SYSDATE + 100 DATEVAL FROM DUAL
UNION
SELECT SYSDATE -500 DATEVAL FROM DUAL
UNION
SELECT SYSDATE + 30 DATEVAL FROM DUAL
UNION
SELECT SYSDATE -30 DATEVAL FROM DUAL
) SELECT * FROM TAB
ORDER BY DATEVAL DESC
I have the query below where the date is hard-coded. My objective is to remove the harcoded date; the query should pull the data for the previous month when it runs.
select count(distinct switch_id)
from xx_new.xx_cti_call_details#appsread.prd.com
where dealer_name = 'XXXX'
and TRUNC(CREATION_DATE) BETWEEN '01-AUG-2012' AND '31-AUG-2012'
Should I use sysdate-15 function for that?
Modifying Ben's query little bit,
select count(distinct switch_id)
from xx_new.xx_cti_call_details#appsread.prd.com
where dealer_name = 'XXXX'
and creation_date between add_months(trunc(sysdate,'mm'),-1) and last_day(add_months(trunc(sysdate,'mm'),-1))
The trunc() function truncates a date to the specified time period; so trunc(sysdate,'mm') would return the beginning of the current month. You can then use the add_months() function to get the beginning of the previous month, something like this:
select count(distinct switch_id)
from xx_new.xx_cti_call_details#appsread.prd.com
where dealer_name = 'XXXX'
and creation_date >= add_months(trunc(sysdate,'mm'),-1)
and creation_date < trunc(sysdate, 'mm')
As a little side not you're not explicitly converting to a date in your original query. Always do this, either using a date literal, e.g. DATE 2012-08-31, or the to_date() function, for example to_date('2012-08-31','YYYY-MM-DD'). If you don't then you are bound to get this wrong at some point.
You would not use sysdate - 15 as this would provide the date 15 days before the current date, which does not seem to be what you are after. It would also include a time component as you are not using trunc().
Just as a little demonstration of what trunc(<date>,'mm') does:
select sysdate
, case when trunc(sysdate,'mm') > to_date('20120901 00:00:00','yyyymmdd hh24:mi:ss')
then 1 end as gt
, case when trunc(sysdate,'mm') < to_date('20120901 00:00:00','yyyymmdd hh24:mi:ss')
then 1 end as lt
, case when trunc(sysdate,'mm') = to_date('20120901 00:00:00','yyyymmdd hh24:mi:ss')
then 1 end as eq
from dual
;
SYSDATE GT LT EQ
----------------- ---------- ---------- ----------
20120911 19:58:51 1
Data for last month-
select count(distinct switch_id)
from xx_new.xx_cti_call_details#appsread.prd.com
where dealer_name = 'XXXX'
and to_char(CREATION_DATE,'MMYYYY') = to_char(add_months(trunc(sysdate),-1),'MMYYYY');
I believe this would also work:
select count(distinct switch_id)
from xx_new.xx_cti_call_details#appsread.prd.com
where
dealer_name = 'XXXX'
and (creation_date BETWEEN add_months(trunc(sysdate,'mm'),-1) and trunc(sysdate, 'mm'))
It has the advantage of using BETWEEN which is the way the OP used his date selection criteria.
It is working with me in Oracle sql developer
SELECT add_months(trunc(sysdate,'mm'), -1),
last_day(add_months(trunc(sysdate,'mm'), -1))
FROM dual
Getting last nth months data retrieve
SELECT * FROM TABLE_NAME
WHERE DATE_COLUMN BETWEEN '&STARTDATE' AND '&ENDDATE';