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

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)

Related

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).

I'm trying to get it to display but it is fetching me null when the output should be 'YES'

I'm trying to get it to display but it is fetching me null when the output should be 'YES'
SELECT STRT_DT,END_DT,SYSDATE AS DT,
CASE
WHEN TO_CHAR(STRT_DT,'MON-YYYY') <= TO_CHAR(SYSDATE,'MON-YYYY')
AND TO_CHAR(END_DT,'MON-YYYY') = TO_CHAR(SYSDATE,'MON-YYYY') THEN 'Yes'
END AS D
FROM
(
SELECT TO_DATE('14-JAN-2022','DD-MON-YYYY') AS STRT_DT
, TO_DATE('05-APR-2022','DD-MON-YYYY') AS END_DT
FROM DUAL);
It is not working because of this line:
TO_CHAR(STRT_DT,'MON-YYYY') <= TO_CHAR(SYSDATE,'MON-YYYY')
you are using 'Comparison Operator' on a string, if it is a date datatype the engine would know what is a 'higher' date between these two but because it is a string this condition won't work the way you intended (it is comparing those strings on alphabetical basis), simple solution would be to replace it just with:
STRT_DT <= SYSDATE
or if u want to compare only month and year:
TRUNC(STRT_DT,'MM') <= TRUNC(sysdate,'MM')
here we are truncating month so only month and year are relevant for comparison in other words if STRT_DT and SYSDATE are in the same year and month the condition will be satisfied even if the STRT_DT is 'higher' (day from the future of that month) then SYSDATE.
It can't work; you're comparing month names. Switch to a different format model which allows meaningful comparing, e.g. YYYYMM instead of MON-YYYY:
SQL> SELECT STRT_DT,
2 END_DT,
3 SYSDATE AS DT,
4 CASE
5 WHEN TO_CHAR (STRT_DT, 'yyyymm') <= TO_CHAR (SYSDATE, 'yyyymm')
6 AND TO_CHAR (END_DT, 'yyyymm') = TO_CHAR (SYSDATE, 'yyyymm')
7 THEN
8 'Yes'
9 ELSE
10 'No'
11 END AS D
12 FROM (SELECT TO_DATE ('14-JAN-2022', 'DD-MON-YYYY') AS STRT_DT,
13 TO_DATE ('05-APR-2022', 'DD-MON-YYYY') AS END_DT
14 FROM DUAL);
STRT_DT END_DT DT D
---------- ---------- ---------- ---
14.01.2022 05.04.2022 22.04.2022 Yes
SQL>

case on where statement with date

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

SQL query not retrieving data

SELECT DISTINCT
TO_CHAR(CREATION_DATE,'MONTH') creation_month
FROM
AP_INVOICES_ALL;
This query retrieves the month properly. But if I pass the month in where clause it doesn't retrieve data.
SELECT DISTCINT
TO_CHAR(CREATION_DATE, 'MONTH') CREATION_MONTH
FROM
AP_INVOICES_ALL
WHERE
TO_CHAR(CREATION_DATE, 'MONTH') = 'MARCH';
Please assist. I need to pass month as parameter in one report.
This is a known issue with 'MONTH' formats. The string is padded with characters.
Instead, use 'MON'. Check this out:
select to_char(sysdate, 'MONTH'),
(case when to_char(sysdate, 'MONTH')= 'APRIL' then 1 else 0 end),
to_char(sysdate, 'MON'),
(case when to_char(sysdate, 'MON')= 'APR' then 1 else 0 end)
from dual;
The first case expression returns 0 -- no match. The second returns 1, indicating that they do match.
I think passing in just the month, without the year, is not a good idea. And you will be far better off treating dates as dates, comparing them to dates, etc. Might I suggest something like the following?
SELECT TO_CHAR(creation_date, 'MONTH') AS creation_month
FROM ap_invoices_all
WHERE TRUNC(creation_date, 'MONTH') = DATE'2018-03-01';
TRUNC()ing the date to the month will return a value of type DATE of the first of the month at midnight. You can then compare using regular Oracle DATE values or ANSI DATE literals as above.
Hope this helps.

How to compare two dates in oracle11g

i am new to oracle. i need to compare date column with the current date in oracle 11g
for an example my table is
srno dob
1 1992-04-01
2 1988-04-01
3 1995-04-01
so i have to compre dob with the sysdate. if it is matched then must show the data.
i have tried this query to get result.
select dob
from xyz
where extract(month from dob)=extract(month from sysdate)
and extract(day from dob)=extract(day from sysdate);
but it is not working. please tell me where am i going wrong.
thanks.
select ...
where to_char(dob,'MMDD')=to_char(sysdate,'MMDD')
There are easier ways to compare two dates in Oracle. Try the solution below:
select random_date_1, random_date_2,
-- when you have to match the complete date
/* use to_char(random_date_1,'Dd-Mon-Yy hh24.mi.ss')
when comparing date time */
/* use to_char(random_date_1,'Dd-Mon-Yy hh24')
when only checking the date and hour (this is actually useful in a scenarios */
case when trunc(random_date_1) = trunc(random_date_2)
then 'Match' else 'No Match' end as method_1,
case when to_char(random_date_1,'Dd-Mon-Yy') = to_char(random_date_2,'Dd-Mon-Yy')
then 'Match' else 'No Match' end as method_2,
-- when you have to match only month
case when trunc(random_date_1,'Mon') = trunc(random_date_2,'Mon')
then 'Match' else 'No Match' end as method_3,
case when to_char(random_date_1,'Mon') = to_char(random_date_2,'Mon')
then 'Match' else 'No Match' end as method_4
from
(select to_date(round (dbms_random.value (24, 31))
|| '-'
|| round (dbms_random.value (01, 01))
|| '-'
|| round (dbms_random.value (2015, 2015)),
'DD-MM-YYYY') + level - 1 random_date_1,
to_date(round (dbms_random.value (27, 31))
|| '-'
|| round (dbms_random.value (01, 01))
|| '-'
|| round (dbms_random.value (2015, 2015)),
'DD-MM-YYYY') + level - 1 random_date_2 from dual
connect by level <= 10);
Try this
SELECT DOB
FROM XYZ
WHERE TRUNC (DOB) = TRUNC (SYSDATE)
As said above use to_char if you need to do a conversion, and look at the different format masks available. If your dob datatype is a date then you can compare directly with the SYSDATE value. As above getting just MMDD will give you just the month (04) and the day (01) as a char string for comparison.
I've just tried out the example you gave in your question and can't see what is wrong with using extract, as you have shown:
select dob
from xyz
where extract(month from dob)=extract(month from sysdate)
and extract(day from dob)=extract(day from sysdate);
Or am I misunderstanding something? You say that the code isn't working but I can't see what you mean.
I prefer to use extract rather than to_char in this sort of situation as I feel that it more clearly represents what I want. I don't want a character representation of the date, I just want to compare the month and the day.
Here is a SQLFiddle with an example: http://sqlfiddle.com/#!4/c545c/2
What is the error you are getting?
In your DB is dob field defined as DATE or varchar2?
In case your DB field is varchar2, then you may have to use,
SELECT * FROM XYZ
WHERE TRUNC ( TO_DATE(DOB, 'YYYY-MM-DD') ) = TRUNC (SYSDATE);