Fetch yesterday details using extract in SQL - sql

consultation(patient_id, cdate, doctor_id)
I want the details of patients which was treated yesterday using extract
But I am getting error
ORA-00911: invalid character
My code:
select *
from consultation
where extract(day from cdate) = extract(day from sysdate) - '1';

You may avoid extract and simply use:
select *
from consultation
where trunc(cdate) = trunc(sysdate-1)
Here I use trunc to remove the time part; also, notice that by using extract to compare the day, you will get not only records of yesterday, but even records from the past months.
If you need to get all the records where the day is 6 (assuming that sysdate is May, 7), no matter the month or year, you can use:
where extract(day from cDate) = extract(day from sysdate -1)

Prefer not to use EXTRACT on the date column, it is less efficient, especially if there's an index or partition on the date column. simply use TRUNC on SYSDATE
select * from consultation where
cdate >= TRUNC(sysdate) - 1
AND cdate < TRUNC(SYSDATE)

you need to put integer 1 not string '1'
select * from consultation where
extract(day from cdate) = extract(day from sysdate) - 1;

Related

Obtain data from Friday, Saturday and Sunday if today is Monday SQL Oracle

I am looking to obtain all data in a table from yesterday in SQL Oracle.
This is simply enough using the WHERE clause, i.e,
SELECT *
FROM My_Data
WHERE TO_DATE(My_Data.Date,'YYYY-MM-DD') = TRUNC(SYSDATE)-1
However if I now need to add more logic where if the day of the query is a Monday (SYSDATE) then obtain data between Friday and Sunday.
Using a between statement is no issue, I'm just not sure if I can include in a where statement given I'm unable to use case statement here.
Thanks
SELECT
*
FROM
My_Data
WHERE
TO_DATE(My_Data.Date,'YYYY-MM-DD')
Between Case When To_Char(SYSDATE, 'DY') = 'MON' Then TRUNC(SYSDATE)-3 ELSE TRUNC(SYSDATE)-1 END
And TRUNC(SYSDATE)-1
You can use the Case expression in Where clause. Regards...
Don't use TO_DATE on a column that is already a date (and if it is a string then don't store dates as strings).
So you are not dependent on the date language session parameter, you can compare the date to the start of the ISO week (which is independent of language) and you can compare on a date range so that Oracle can use an index on your date column:
SELECT *
FROM My_Data
WHERE "DATE" < TRUNC(SYSDATE)
AND "DATE" >= CASE TRUNC(SYSDATE) - TRUNC(SYSDATE, 'IW')
WHEN 0 -- Monday
THEN TRUNC(SYSDATE) - 3
ELSE TRUNC(SYSDATE) - 1
END;
or:
SELECT *
FROM My_Data
WHERE "DATE" < TRUNC(SYSDATE)
AND ( ( TRUNC(SYSDATE) - TRUNC(SYSDATE, 'IW') = 0 AND "DATE" >= TRUNC(SYSDATE) - 3 )
OR "DATE" >= TRUNC(SYSDATE) - 1
);

Add days Oracle SQL

SELECT ORDER_NUM, CUSTOMER_NUM, CUSTOMER_NAME, ADD_DAYS (ORDER_DATE, 20)
FROM CUSTOMER, ORDERS;
Oracle Express says ADD_DAYS invalid? Any ideas what Am I doing wrong?
If you want to add N days to your days. You can use the plus operator as follows -
SELECT ( SYSDATE + N ) FROM DUAL;
You can use the plus operator to add days to a date.
order_date + 20
In a more general way you can use "INTERVAL". Here some examples:
1) add a day
select sysdate + INTERVAL '1' DAY from dual;
2) add 20 days
select sysdate + INTERVAL '20' DAY from dual;
2) add some minutes
select sysdate + INTERVAL '15' MINUTE from dual;
Some disadvantage of "INTERVAL '1' DAY" is that bind variables cannot be used for the number of days added. Instead, numtodsinterval can be used, like in this small example:
select trunc(sysdate) + numtodsinterval(:x, 'day') tag
from dual
See also: NUMTODSINTERVAL in Oracle Database Online Documentation
It's Simple.You can use
select (sysdate+2) as new_date from dual;
This will add two days from current date.
One thing about
select (sysdate+3) from dual
is that the sysdate is interpreted as date.
But if you want to use a custom date, not local, you need to make sure it is interpreted as date, not string. Like so (adding 3 days):
select (to_date('01/01/2020')+3) from dual

Delete rows by date in ANSI SQL

I want to remove rows from last day, I have a date column, how can I do this in ansi?
delete from mytable where mydate < current_date;
This query deletes both yesterday's and today's records, I want to keep today's records ('today' is from 12 am onwards)
Your statement is valid ANSI SQL and will work on any DBMS that complies with the ANSI SQL specification with regards to DATE handling.
With Oracle the situation is different: a DATE column/value always contains a time as well. So current_date (or sysdate which is the same for the sake of this discussion) will not return 2014-09-17 but e.g. 2014-09-17 16:54:12.
Now if you have a row in your table that contains 2014-09-17 08:54:12 the condition mydate < current_date will be true because 08:54:12 is smaller than 16:54:12 and thus the row will be deleted.
You need to rewrite your statement to:
delete from mytable
where trunc(mydate) < trunc(current_date);
trunc() set the time part of a DATE to 00:00:00 and thus the comparison behaves as if there was no time part involves (because it's the same for both comparison values).
If you really, really need to write this condition in ANSI SQL and taking Oracle's non-standard DATE handling into account you need to do something like this:
select *
from mytable
where (extract(year from mydate) < extract(year from current_date))
or (extract(year from mydate) = extract(year from current_date) and extract(month from mydate) < extract(month from current_date))
or (extract(year from mydate) = extract(year from current_date) and extract(month from mydate) = extract(month from current_date) and extract(day from mydate) < extract(day from current_date));
The extract() function as shown is ANSI SQL.

How do I determine the last day of the previous month using PostgreSQL?

I need to query a PostgreSQL database to determine records that fall within today's date and the last day of the previous month. In other words, I'd like to retrieve everything that falls between December 31, 2011 and today. This query will be re-used each month, so next month, the query will be based upon the current date and January 31, 2012.
I've seen this option, but I'd prefer to avoid using a function (if possible).
Both solutions include the last day of the previous month and also include all of "today".
For a date column:
SELECT *
FROM tbl
WHERE my_date BETWEEN date_trunc('month', now())::date - 1
AND now()::date
You can subtract plain integer values from a date (but not from a timestamp) to subtract days. This is the simplest and fastest way.
For a timestamp column:
SELECT *
FROM tbl
WHERE my_timestamp >= date_trunc('month', now()) - interval '1 day'
AND my_timestamp < date_trunc('day' , now()) + interval '1 day'
I use the < operator for the second condition to get precise results (read: "before tomorrow").
I do not cast to date in the second query. Instead I add an interval '1 day', to avoid casting back and forth.
Have a look at date / time types and functions in the manual.
For getting date of previous/last month:
SELECT (date_trunc('month', now())::date - 1) as last_month_date
Result: 2012-11-30
For getting number of days of previous/last month:
SELECT DATE_PART('days', date_trunc('month', now())::date - 1) last_month_days
Result: 30
Try this:
SELECT ...
WHERE date_field between (date_trunc('MONTH', now()) - INTERVAL '1 day')::date
and now()::date
...
Try
select current_date - cast((date_part('day', current_date) + 1) as int)
take from http://wiki.postgresql.org/wiki/Date_LastDay, and modified to return just the days in a month
CREATE OR REPLACE FUNCTION calc_days_in_month(date)
RETURNS double precision AS
$$
SELECT EXTRACT(DAY FROM (date_trunc('MONTH', $1) + INTERVAL '1 MONTH - 1 day')::date);
$$ LANGUAGE 'sql' IMMUTABLE STRICT;
select calc_days_in_month('1999-05-01')
returns 31
Reference is taken from this blog:
You can use below function:
CREATE OR REPLACE FUNCTION fn_GetLastDayOfMonth(DATE)
RETURNS DATE AS
$$
SELECT (date_trunc('MONTH', $1) + INTERVAL '1 MONTH - 1 day')::DATE;
$$ LANGUAGE 'sql'
IMMUTABLE STRICT;
Sample executions:
SELECT *FROM fn_GetLastDayOfMonth(NOW()::DATE);

Oracle SQL Where Clause against a date column

I have a DATE column with a date in it but I need to query it to find records less than 30 days old.
START_DATE
----------
01-AUG-2010
09-AUG-2010
22-AUG-2010
09-SEP-2010
Query:
SELECT START_DATE
WHERE START_DATE < 30;
I know it is simple Query in ORACLE SQL but i am doing something wrong.
Use:
SELECT t.start_date
FROM YOUR_TABLE t
WHERE t.start_date > SYSDATE - 30
SYSDATE is Oracle's syntax to get the current date and time
In Oracle, you can do date arithmetic in the context of days, so SYSDATE - 30 means "current date, subtract thirty days" to get a date that is thirty days in the past
If you want to evaluate the date based on thirty days as of midnight, use the TRUNC function:
SELECT t.start_date
FROM YOUR_TABLE t
WHERE t.start_date > TRUNC(SYSDATE) - 30
Don't run TRUNC on the column - that will render an index on the column useless, ensuring a table scan.
SELECT t.start_date
FROM YOUR_TABLE t
WHERE t.start_date > SYSDATE - INTERVAL '30' DAY;
INTERVAL is more portable than assuming that you can add or subtract days, although I've noticed some slight differences in the INTERVAL syntax between Oracle and PostgreSQL.
WHERE START_DATE > SYSDATE - 1
or perhaps
WHERE TRIM(STARTDATE) > TRIM(SYSDATE) - 1