case on where statement with date - sql

I am trying to filter data on a date based on month. I went through different solutions in here but couldn't get it to work. I am trying to filter if month is less than march to use 2020 else get 2021 data.
I have tried 2 solutions based on different feed back:
select *
from db.table1
where
(case
(to_char(commit_date, 'mm')<'03') then
(to_char(commit_date, 'mm')= (to_char(sysdate, 'mm')-1)
and to_char(commit_date, 'yyyy') = '2020')
else
(to_char(commit_date, 'mm')= (to_char(sysdate, 'mm')-1)
and to_char(commit_date, 'yyyy') = '2021')
end)
This gives mme invalid relational operator.
Another solution
select *
from db.table1
where
(
(to_char(commit_date, 'mm')<'03' and to_char(commit_date, 'yyyy') = '2020') or (to_char(commit_date, 'yyyy') = '2021'))
doesn't seem to filter.
Thanks,
Sam

You can try to use TO_DATE function greater and equal than 2020-01-01 and smaller than 2020-03-01 or EXTRACT year equal 2021
SELECT *
FROM db.table1
WHERE
(commit_date >= TO_DATE('2020-01-01', 'yyyy-mm-dd') AND commit_date < TO_DATE('2020-03-01', 'yyyy-mm-dd'))
OR
EXTRACT(YEAR FROM commit_date) = 2021

Related

SQL Query to pass multiple parameter with <= instead of in

I am passing two parameters - Month and year
Month can be 01/2022, 02/2022, 03/2022 etc
Year can be 2022, 2021,2020
Year is mandatory
I have a condition in the query that compares these dates -
SELECT Max(acrl2.accrual_period)
FROM anc_per_accrual_entries acrl2
WHERE person_id = 123
AND acrl2.plan_id = 1678
acrl2.accrual_period
and to_char(acrl2.accrual_period,'yyyy') = NVL(:p_year,to_char(acrl2.accrual_period,'yyyy'))
AND acrl2.accrual_period <= Nvl((
CASE
WHEN :p_month IS NOT NULL
THEN To_date(To_char(Last_day(To_date(:p_month, 'yyyy/mm')), 'yyyymmdd'), 'yyyymmdd')
WHEN :p_year IS NOT NULL
THEN To_date(:p_year || '1231', 'yyyymmdd')
END) ,sysdate)
When i pass one month - say 01/2022 - I am getting the correct output. or when i am passing just 2021, I am getting an output.
The issue is when i select multiple months 01/2022, 02/2022 or 2021,2022.
I know i can use in clause. But I am not being able to use it with <=
Not sure about what you expect when the conditions are met, but herre is what you can do with the conditions themselves. Case works in a way that it will accept the first WHEN condition satisfied end exits. So, if first when cond is true the second is not considered at all. I split the two (month, year) to be tested both. Also there is INSTR function which tests p_month and p_year.
SELECT
Max(acrl2.accrual_period)
FROM
anc_per_accrual_entries acrl2
WHERE
person_id = 123 And
acrl2.plan_id = 1678 And
TRUNC(acrl2.accrual_period, 'dd') <= (CASE
WHEN Instr(:p_month, To_Char(acrl2.accrual_period, 'mm/yyyy')) > 0
THEN To_Date(To_char(Last_day(acrl2.accrual_period), 'yyyymmdd'), 'yyyymmdd')
END) And
TRUNC(acrl2.accrual_period, 'dd') <= (CASE
WHEN Instr(:p_year, To_Char(acrl2.accrual_period, 'yyyy')) > 0
THEN To_Date(To_char(acrl2.accrual_period, 'yyyy') || '1231', 'yyyymmdd')
END)

SQL Query to fetch data as of the year,quarter or month passed in parameter

I have the following query-
(SELECT DISTINCT accrual_period
FROM anc_per_accrual_entries a,
anc_per_plan_enrollment b
WHERE a.per_plan_enrt_id = b.per_plan_enrt_id
--AND a.accrual_period = b.last_accrual_run
AND b.work_term_asg_id = paam.work_terms_assignment_id
AND accrual_period = (SELECT Max(acrl2.accrual_period)
FROM anc_per_accrual_entries acrl2
WHERE person_id = paam.person_id
AND acrl2.plan_id = appe.plan_id
AND acrl2.accrual_period <= sysdate)
AND b.plan_id = appe.plan_id
AND b.person_id = paam.person_id
AND sysdate BETWEEN b.enrt_st_dt AND b.enrt_end_dt)
I have the following query to fetch accrual_period as of the sysdate or today. Now there are three parameters -
P_YEAR - 2022
P_QUARTER - 2022 Q 4
P_MONTH - 2022 / 12
If the year is passed - I want the query to fetch the data as of current month and date of that year. i.e. the sysdate in the query should be replaced by 2021/05/06 if i pass year as 2021.
If i pass Year and quarter of that year then the sysdate in the query should be replaced
by that quarter. i.e. if the quarter is 2021 Q 1, then it should be calculated as of the last date of that quarter i.e. 31 march 2021.
If I pass month, then the last day of month
How can i achieve it in the same query ?
To me, it looks like the following where clause (which is to be applied to query you already posted):
where accrual_period >=
case when :p_year is not null then
to_date(:p_year || to_char(sysdate, 'mmdd'), 'yyyymmdd')
when :p_quarter is not null then
last_day(to_date(substr(:p_quarter, 1, 4) || case substr(:p_quarter, -1)
when '1' then '03'
when '2' then '06'
when '3' then '09'
when '4' then '12
end, 'yyyymm'))
when :p_month is not null then last_day(:p_month, 'yyyy / mm')
end;
As of your comment regarding an "invalid argument" error and doubt about the last_day function: everything is just fine when I run it (I don't have your tables nor data, but such a dummy query works OK):
SQL> with test(col) as
2 (select '2022 Q 4' from dual)
3 select last_day(to_date(substr(col, 1, 4) || case substr(col, -1) when '1' then '03'
4 when '2' then '06'
5 when '3' then '09'
6 when '4' then '12' end, 'yyyymm')) result
7 from test;
RESULT
----------
31.12.2022
SQL>

Case Date Filter in Where Clause - Oracle

I'm trying to return a date range dependent on current_date. The logic is as follows:
If the current month is January then return the beginning of the prior year; otherwise return the beginning of the current year.
The attached code keeps throwing a syntax error. I'm using a NS 64bit ODBC in Alteryx to pull the info.
Code :
and t.TRANDATE between
--period beg
(case
when to_char(current_date, 'MM')='01' then add_months(trunc(current_date, 'YYYY'),-12)
else trunc(current_date, 'YYYY')
end)
and
--period end
trunc(current_date,'MM')-1/84600)
Any suggestions on how to clear the syntax error or restructure the statement?
You can use:
AND t.TRANDATE >= TRUNC(ADD_MONTHS(current_date, -1), 'YYYY')
AND t.TRANDATE < TRUNC(current_date,'MM')
Syntax error? Which syntax error? I don't get any:
SQL> select *
2 from dual
3 where sysdate not between
4 case when to_char(current_date, 'mm') = '01' then add_months(trunc(current_date, 'YYYY'),-12)
5 else trunc(current_date, 'yyyy')
6 end
7 and trunc(current_date, 'mm') - 1/84600;
D
-
X
SQL>
(I used NOT BETWEEN and the DUAL table as I don't have your table(s), just to show that this code works OK).

Oracle : Selecting date by month with where clause

I came across a problem that in selecting the date for current desired month and year. I tried the 2 statements shown below but failed to execute the query
select to_char(sysdate, 'Month') from income
select * from income where to_char(sysdate,month) = 'feb'
Update
But after researching and learning more in depth on oracle docs website. What i came out with is to use "between" clause. Specifying the first day and last day of the month . Doing so, it will execute the desired month/year
For an example
SELECT column_name
FROM table_name where column_name = (Your own value) AND
column_date >= to_date('01/02/2012', 'dd/mm/yyyy')
and column_date < to_date('01/03/2012', 'dd/mm/yyyy')
I hope this help :)
Are you after something like:
select *
from income
where <date_column> >= to_date('01/05/2019', 'dd/mm/yyyy')
and <date_column> < to_date('01/06/2019', 'dd/mm/yyyy')
(replacing <date_column> with the name of the date column in your income table that you want to filter on)?
I think you can use the following query:
select *
from income
where to_char(<date_column>,'MON-RRRR') = 'MAY-2019';
If you want to pass in a string like 'May 2012', then I would recommend:
select i.*
from income i
where i.datecol >= to_date('May 2012', 'Mon YYYY') and
i.datecol < to_date('May 2012', 'Mon YYYY') + interval '1' month;
That said, I think your application should turn the string value into a date range and you should use that range in your query:
select i.*
from income i
where i.datecol >= :datestart
i.datecol < :dateend + interval '1 day';
I strong encourage you to avoid between with dates, particularly in Oracle. The date data type has a built-in time component, and that can throw off the comparisons.

How to get Year and Month of a DATE using Oracle

How can I get the year and month of a date in the where clause using Oracle.
I used to be working with SQL server and it was as simple as YEAR(FIELDNAME) and MONTH(FIELDNAME).
I have tried the following:
SELECT *
FROM myschema.mytablename
WHERE EXTRACT(YEAR FROM myDATE) = 2017
however it gives ORA-30076 Error
Have you tried EXTRACT()?
SELECT EXTRACT(YEAR FROM DATE '2017-12-01') FROM DUAL;
2017
SELECT EXTRACT(MONTH FROM DATE '2017-12-01') FROM DUAL;
12
I tried this in sql fiddle with 11g and it works in WHERE clause too.
http://sqlfiddle.com/#!4/fb2b09/2
SELECT *
FROM myschema.mytablename
WHERE TO_CHAR(myDATE, 'YYYY') = '2017';
Explicitly convert year part of DATE into CHAR and compare it with literal.
For year and month comparison:
SELECT *
FROM myschema.mytablename
WHERE TO_CHAR(myDATE, 'YYYY') = '2017' AND TO_CHAR(myDate, 'MM') = '07';
Your query should work, but a better alternative would be
SELECT *
FROM YOUR_TABLE
WHERE MY_DATE BETWEEN TO_DATE('01-JAN-2017', 'DD-MON-YYYY')
AND TO_DATE('01-JAN-2018', 'DD-MON-YYYY') - INTERVAL '1' SECOND
Best of luck.
I did this with the function EXTRACT() and it works good for me.
I'm gonna share the query code here:
SELECT extract(YEAR from s.CREATE_DATE) as YEAR, extract(MONTH from s.CREATE_DATE) as MONTH, s.SALES_PERSON_GID, COUNT(s.SALES_ORDER_ID) as "TOTAL ORDERS" FROM SALES_ORDERS s, SALES_ORDER_STATUS ss WHERE s.SALES_ORDER_ID = ss.SALES_ORDER_ID and ss.STATUS_TYPE_ID = 'SALE ORDER STATUS' and ss.STATUS_VALUE_GID = 'SALE ORDER STATUS_DELIVERED' GROUP BY s.SALES_PERSON_GID,s.CREATE_DATE