How to get data from first day of the month until yesterday - oracle

does anyone know the query to get data from first day of the month until yesterday? I Try using query below but the problem is when today is the first day of the month, so the value become between 20170201 and 20170131
select * from a where to_char(DATE,'yyyymmdd') BETWEEN to_char(sysdate,'yyyymm')||'01' and to_char(sysdate-1,'yyyymmdd')
Ex: if today is 01-02-2017 i want to select the data from 01-01-2017 until 31-01-2017, but if today is 13-02-2017 i want to select the data from 01-02-2017 until 12-02-2017, thank's before

This question has been updated with your new logic. The query below will retain records under the following conditions:
someDate falls between the first day and yesterday of the current month, or
someDate, when today is the first of the month, falls anywhere in the previous month
SELECT *
FROM yourTable
WHERE someDate BETWEEN CASE WHEN EXTRACT(DAY FROM SYSDATE) = 1
THEN TRUNC(SYSDATE-1, 'MONTH')
ELSE TRUNC(SYSDATE, 'MONTH') END AND
CASE WHEN EXTRACT(DAY FROM SYSDATE) = 1
THEN TRUNC(SYSDATE, 'MONTH') - 1
ELSE TRUNC(SYSDATE - 1) END
This query assumes that you have a DATE column called someDate.

Related

how to get year and month into number oracle

i'm trying to get sysdate year and month into number or char.
I'd want something like this:
202107
or last month
202106
i tried this code:
select trunc(add_months(sysdate, -1), 'MM') from dual;
please help, thanks
Convert it to a string and then to a number:
SELECT TO_NUMBER(TO_CHAR(ADD_MONTHS(SYSDATE,-1), 'YYYYMM'))
FROM DUAL;
Or, you can use extract and wrap it in a sub-query so you do not need to repeat adding the months:
SELECT EXTRACT(YEAR FROM dt) * 100 + EXTRACT(MONTH FROM dt)
FROM (
SELECT ADD_MONTHS(SYSDATE, -1) AS dt
FROM DUAL
)
Like
SELECT EXTRACT(year from sysdate) * 100 + EXTRACT(month from sysdate)
If you want to scroll around, manipulate the date before you extract from it, rather than minusing after you extract (gets tricky to e.g. go back a month if the date is in jan)
--will work for jan 2021
SELECT EXTRACT(year from ADD_MONTHS(somedate, -1)) * 100 + EXTRACT(month from ADD_MONTHS(somedate, -1))
--won't work for jan 2021
SELECT EXTRACT(year from somedate) * 100 + (EXTRACT(month from somedate) - 1)
TRUNC is a device that "rounds" a date to a particular interval, such as "trimming the time off a datetime" or "making any day of the week back to the date that was the start of the week" - very useful for all sorts of stuff like "total sales by month - SUM(sale) GROUP BY TRUNC(saledate, 'mm')" but it keeps all the components of the date (the day, the hour, the minute etc) so it isn't what you want.

Get 9 AM of current day in Oracle

Can anyone tell me how to get 9AM of the current day in Oracle?
In SQL Server I would do the following:
SELECT DATEADD(day, DATEDIFF(day, 0, GETDATE()), '09:00:00')
I'm writing a stored procedure that only retrieves data from 9 AM of the same day.
Just take the current day at midnight and add nine hours
trunc(sysdate) + interval '9' hour
select trunc(sysdate) +9/24 from dual;
Try to get 9AM of the current day in Oracle using the following:
select to_char(trunc(sysdate + 1) + 9/24, 'HH')|| 'AM' as "current day 9AM"
from dual;

Using "today" and "two days before" in date with Oracle

I have the following WHEREclause in a query:
SELECT ...
FROM ...
WHERE IMPORT_DATE between
to_date('2018-03-16 00:00:00', 'yyyy-mm-dd hh24:mi:ss') and
to_date('2018-03-16 23:59:59', 'yyyy-mm-dd hh24:mi:ss')
And I would like to write two new queries:
One with this same clause but using "today" instead of "2018-03-16".
Another with the same clause but using "the day before yesterday" (today - 2) instead of "2018-03-16".
How can I do this in Oracle?
As Oracle has no real DATE data type and always includes a time, it's usually better to not use between for conditions like that, but to use >= together with < compared to midnight the next day.
To find the rows from "today" use:
SELECT ...
FROM ...
WHERE import_date >= trunc(sysdate)
AND import_date < trunc(sysdate) + 1;
or:
SELECT ...
FROM ...
WHERE import_date >= trunc(sysdate) - 2
AND import_date < (trunc(sysdate) - 2) + 1;
The parentheses aren't really required in the second expression, they are just there to document that it's the same expression as the first one.
select trunc(sysdate) from dual;
Returns today's date without any time
select trunc(sysdate) - interval '2' day from dual;
Returns the day 2 days before today without time.
You can also use month, hour, year etc instead of day.

Between with Variables for prior months start and stop

I use the following WHERE with sysdate to get a between range.
WHERE TO_CHAR(mopstart, 'yyyy-mm-dd hh24:mi:ss') BETWEEN TO_CHAR(sysdate,'YYYY-MM-DD')||' 21:00:00' AND TO_CHAR(sysdate+1,'YYYY-MM-DD')||' 20:59:59'
My question is, how do I create a BETWEEN with variables for the date to return the prior months start and end date?
You would usually not use BETWEEN for this. As in real life you would not say "the time from beginning of last month till the end of last month", but just "last month", so you would do in SQL.
Knowing that a month is actually the year and the month:
where extract(year from mopstart) = extract(year from sysdate)
and extract(month from mopstart) = extract(month from sysdate) - 1
Or:
where to_char(mopstart,'yyyymm') = to_char(add_months(sysdate,-1),'yyyymm')
If I understand you well, that would be:
where ... between trunc(add_months(sysdate, -1), 'MON') and trunc(sysdate, 'MON') - 1
One more thing: don't use TO_CHAR to compare dates, just use dates and intervals.

Grouping by Fiscal Year (Oracle)

Is there a way in Oracle that can pull the FY? I used the script below to pull just two FY. Mytable date range is from FY1998 to FY2009.
SELECT 'FY2008' as FY,
Site,
COUNT(*)
FROM mytable
WHERE date >='10-OCT-2007'
AND date <'10-OCT-2008'
GROUP BY site
SELECT 'FY2008' as FY,
Site,
COUNT(*)
FROM mytable
WHERE date >='10-OCT-2008'
AND date <'10-OCT-2009'
GROUP BY site
Pulling two FY is OK but it's too much repeatative when pulling more than 10 FY.
Add 83 days to your date and truncate it to whole year:
select 'FY'||TRUNC(date + 83, 'YYYY') as FY, Site, count(*)
from mytable
group by 'FY'||TRUNC(date + 83, 'YYYY'), site
Assuming Oracle 9i+, use a CASE expression:
SELECT CASE
WHEN TO_CHAR(t.date, ) = 10 AND EXTRACT(DAY FROM t.date) >= 10 THEN
'FY' || EXTRACT(YEAR FROM t.date) + 1
WHEN TO_CHAR(t.date, ) > 10 THEN
'FY' || EXTRACT(YEAR FROM t.date) + 1
ELSE
'FY' || EXTRACT(YEAR FROM t.date)
END AS FY,
t.site,
COUNT(*)
FROM YOUR_TABLE t
GROUP BY t.site, FY
And for completeness, in addition to #eumiro answer. In countries (such as Australia) which have a financial year running from 1 July to 30 June, you can replace the 83 with 184.
A few options:
You can use the to_char function here. Check this link for an explanation:
http://www.techonthenet.com/oracle/functions/to_char.php
You may also try using a case statement
select case when date >='10-OCT-2007' and date <'10-OCT-2008' then 'FY08'
when date >='10-OCT-2008' and date <'10-OCT-2009' then 'FY09'
else 'Other' end as fiscal_year, count(*)
from mytable
group by case when date >='10-OCT-2007' and date <'10-OCT-2008' then 'FY08'
when date >='10-OCT-2008' and date <'10-OCT-2009' then 'FY09'
else 'Other' end
Ultimately, if you have create table privileges you may want to consider making a date lookup table. Search for "date dimension" in data warehousing guides.
For example:
Your table would have
date, date_desc, fiscal_year, etc....
then you could just join and group by fiscal year, or whatever else you want.
Here is another way to easily determine the Fiscal Year of a date for those who's Fiscal Year runs from July to June:
SELECT 'FY'||TO_CHAR(ROUND(your_date_here,'YEAR'),'YY') AS FY

Resources