Issue with Case and Extract Function - oracle

I am writing a SELECT Query as below
SELECT COUNT(*) AS Number_of_rows
FROM PAY_DETL
WHERE
CASE
WHEN
Extract(MONTH FROM CURRENT_DATE) > 9
THEN
Extract(YEAR FROM PAY_EVT_BGN_DT) = Extract(YEAR FROM CURRENT_DATE) AND Extract(MONTH FROM CURRENT_DATE) > 9;
Where i am getting below error
ORA-00905: missing keyword
00905. 00000 - "missing keyword
statement where i am getting error is Extract(YEAR FROM PAY_EVT_BGN_DT "here")
Could someone please help me with above?
Thanks

A query nor a comment you posted help much; what does "not assign" mean?
Anyway: you can't use a conditional WHERE clause that way. A simple option is to split the query into two parts and UNION them, having the "distinguishing" parts of the WHERE clause opposite.
For example:
select count(*) as number_of_rows
from pay_detl
where extract(year from pay_evt_bgn_dt) = extract(year from current_date)
and extract(month from current_date) > 9 --> this condition ...
union
select count(*) as number_of_rows
from pay_detl
where condition_different_from_the_one_above
and extract(month from current_date) <= 9 --> ... is just the opposite from this one
If it doesn't help, please, modify the question, provide test case so that we'd see the input and describe what would the output look like (based on that input).

We must differentiate the two main conditions <,> 9. Then, there is to account for each case:
SELECT SUM(CASE WHEN Extract(MONTH FROM SYSDATE) > 9 THEN
DECODE(Extract(YEAR FROM PAY_EVT_BGN_DT), Extract(YEAR FROM CURRENT_DATE), 1, 0)
END COUNT_MORE_NINE),
SUM(CASE WHEN Extract(MONTH FROM SYSDATE) <= 9 THEN
1
END COUNT_ANOTHER)
FROM PAY_DETL;

Related

encountered the symbol FROM when expecting one of the following pl sql

I am trying to extract year from datefield but when I use extract (year from
datefield) I get this error
Encountered the symbol FROM when expecting one of the following pl sql
cursor o1 is
select substr(tarifa,1,2), count(*)
from pol p, uvod u, doppov d
where extract(year FROM datum_dop) = EXTRACT(YEAR FROM sysdate)
and izdavanje >='1-jul-13'
and p.orgjed = u.sorgz (+)
and DATUM_PREKIDA is not null
and p.polica=d.polica and d.pov_dopl='P'
and d.status='F'
and cisti_ao(p.polica)!=0
group by substr(tarifa,1,2);
Where did I made mistake ?
Ah, this is Forms, probably 6i.
Its engine doesn't know extract function. Change that line to
where to_char(datum_dop, 'yyyy') = to_char(sysdate, 'yyyy')
This would, though, make index on datum_dop column (if it exists) unusable and force Oracle to convert dates to strings, so you'd rather try with
where datum_dop >= trunc(sysdate, 'yyyy')
and datum_dop < add_months(trunc(sysdate, 'yyyy'), 12)
Other than that:
count(*) should have an alias (if you plan to use it), e.g. count(*) as broj_tarifa
if izdavanje is date, don't compare it to a string ('1-jul-13') but date, e.g. izdavanje >= to_date('01.07.2013', 'dd.mm.yyyy')
use table aliases for all columns

Getting ParseException when running Hive query

I'm trying to find the number of employees who are paid less than average wage.
I'm pretty new to hive and struggling a bit, could someone explain whats wrong with my statement and help me out please?
My statement -
SELECT COUNT(*) FROM(SELECT wage, AVG(wage) AS avgWage FROM emp_wages) WHERE wage < avgWage;
The error -
ParseException line 1:82 cannot recognize input near 'where' 'wage' '<' in subquery source
Any help appreciated!
A syntax error. Derived table should be aliased.
SELECT COUNT(*)
FROM (SELECT wage, AVG(wage) AS avgWage FROM emp_wages group by wage) t --alias needed here
WHERE wage < avgWage;
Query wise, it needs a change.
select count(*)
from (SELECT wage, AVG(wage) over() AS avgWage
FROM emp_wages
) t
where wage < avgWage
SELECT COUNT(*)
FROM (SELECT wage, AVG(wage) AS avgWage FROM emp_wages group by wage)avg --group by needed
WHERE wage < avgWage;
The problem is AVG is an aggregation function. If you want to map one to many relations, you need to use a cross join function:
select
count(*), avg(v1.wage),
sum(case when v.wage < v2.avgwage then 1 else 0 end) below_average
from
emp_wages v cross join (select avg(wage) as avgwage from emp_wages) as v2
The correct query would be:
select count(*) where wage <(select avg(wage) from emp_wages);
You are getting a parsing error as wage and avgWage is in subquery.

ORA-00979: not a GROUP BY expression (Case statement issue)

I am getting the ORA-00979 error message on the following query. I should preface this by stating that I've read many of the discussions on this error on Stack Overflow and still cannot find a solution. I'm also confident the error is coming from the CASE statement, because when I completely removed the statement the query has yielded results, and I also received results when I removed all of the CASE statement except the 'SUM(Z.EQUITY_FOUR)' (that is, I'm also confident there is not an issue with the database EQUITY_FOUR is pulling from).
SELECT
EXTRACT(YEAR FROM HDS.MORTGAGE_START_DATE) as Yr,
EXTRACT(MONTH FROM HDS.MORTGAGE_START_DATE) as Mth,
Q.CITY as City,
CASE WHEN pp.ISACTIVE = 'NO'
AND EXTRACT(YEAR FROM HDS.CANCELLATION_DATE) = EXTRACT(YEAR FROM HDS.MORTGAGE_START_DATE)
AND EXTRACT(MONTH FROM HDS.CANCELLATION_DATE) = EXTRACT(MONTH FROM HDS.MORTGAGE_START_DATE)
THEN SUM(Z.EQUITY_FOUR)
END as Cancelled
(From Statement)
(Where Statement)
GROUP BY EXTRACT(YEAR FROM HDS.MORTGAGE_START_DATE),
EXTRACT(MONTH FROM HDS.MORTGAGE_START_DATE),
Q.CITY,
CASE
WHEN pp.ISACTIVE = 'NO'
AND EXTRACT(YEAR FROM HDS.CANCELLATION_DATE) = EXTRACT(YEAR FROM HDS.MORTGAGE_START_DATE)
AND EXTRACT(MONTH FROM HDS.CANCELLATION_DATE) = EXTRACT(MONTH FROM HDS.MORTGAGE_START_DATE)
THEN SUM(Z.EQUITY_FOUR)
END
Concerning the CASE statement in the Group BY clause, while doing my research I read this (ORA-00979: not a GROUP BY expression issue) post which contains two responses stating to add the complete CASE statement to the GROUP BY expression and which the author of the post claims worked for his query. I'm still getting the above-specified error, however.
Thanks for any help!
I think you want the CASE inside the SUM():
SELECT EXTRACT(YEAR FROM HDS.MORTGAGE_START_DATE) as Yr,
EXTRACT(MONTH FROM HDS.MORTGAGE_START_DATE) as Mth,
Q.CITY as City,
SUM(CASE WHEN pp.ISACTIVE = 'NO' AND
EXTRACT(YEAR FROM HDS.CANCELLATION_DATE) = EXTRACT(YEAR FROM HDS.MORTGAGE_START_DATE) AND
EXTRACT(MONTH FROM HDS.CANCELLATION_DATE) = EXTRACT(MONTH FROM HDS.MORTGAGE_START_DATE)
THEN Z.EQUITY_FOUR
END) as Cancelled
(From Statement)
(Where Statement)
GROUP BY EXTRACT(YEAR FROM HDS.MORTGAGE_START_DATE),
EXTRACT(MONTH FROM HDS.MORTGAGE_START_DATE),
Q.CITY;

Distinct the extract month for oracle

Below is my query to extract month from date,
Select distinct Extract (Month From Dates) As Bulan, Count(Matric_No) As Total,Matric_No
From Stud_Sick
Group By Matric_No,Dates
Order By Dates;
This give me error 'not a SELECTED expression'. Anyone know how to fix this?
I suspect you're after the following:
select extract(month from dates) bulan,
count(matric_no) as total,
matric_no
from stud_sick
group by extract(month from dates),
matric_no
order by extract(month from dates);
Or possibly you're after:
select extract(month from dates) bulan,
count(matric_no) as total
from stud_sick
group by extract(month from dates)
order by extract(month from dates);

update a table using a stored procedure in oracle

I have a table t_time where I have the below attributes
time_key, calendar_dt, cal_year, cal_quarter, cal_month, cal_week, week_in_month, cal_st_dt_of_wk, cal_end_dt_of_wk, rfrsh_dt, cal_yyyymm
select * from t_time where time_key = (select max(time_key) from t_time);
74937 31-12-2015 2015 4 12 5 5 27-12-2015 02-01-2016 17-07-2009 201512
I want to write a stored proc such that when i specify the year,t_time should be inserted with all the keys and other attributes..
like
for 2016
time_key calendar_dt cal_year cal_quarter cal_month cal_week week_in_month cal_st_dt_of_wk cal_end_dt_of_wk rfrsh_dt cal_yyyymm
74938 01-01-2016 2016 1 1 1 1 01-01-2016 02-01-2016 22-04-2015 201601
74939 02-01-2016 2016 1 1 1 1 01-01-2016 02-01-2016 22-04-2015 201601
74940 03-01-2016 2016 1 1 2 2 03-01-2016 09-01-2016 22-04-2015 201601
74941 04-01-2016 2016 1 1 2 2 03-01-2016 09-01-2016 22-04-2015 201601
cal_end_dt_of_wk is saturday of that week
cal_st_dt_of_wk is sunday of that week
can someone give me an idea to start with..
time_key - time_key + 1
calendar_dt - select sysdate from dual;
cal_year - select extract(year from sysdate) from dual;
cal_quarter - select case when extract(month from sysdate) in (1,2,3) then 1
case when extract(month from sysdate) in (4,5,6) then 2
case when extract(month from sysdate) in (7,8,9) then 3
case when extract(month from sysdate) in (10,11,12) then 4 else 0 end as cal_quarter from dual;
cal_month - select extract(month from sysdate) from dual;
cal_week - select to_char(to_date(sysdate),'ww') from dual;
week_in_month - select to_char(to_date(sysdate),'w') from dual;
cal_st_dt_of_wk - select trunc(sysdate,'iw')-1 from dual;
cal_end_dt_of_wk - select trunc(sysdate,'iw')+5 from dual;
rfrsh_dt - select sysdate from dual;
cal_yyyymm - select to_char(sysdate,'yyyymm') from dual;
Ok, it's a lot of stuff ;) but I think this should work now:
-- provide year as YYYY
CREATE OR REPLACE PROCEDURE fill_table (year IN VARCHAR2) IS
date_holder DATE := TO_DATE ('01.01.' || year,'DD.MM.YYYY');
BEGIN
WHILE (TO_CHAR (date_holder,'YYYY') = year) LOOP
INSERT INTO t_time
VALUES (1,
date_holder,
extract(year from date_holder),
case when extract(month from date_holder) in (1,2,3) then 1
when extract(month from date_holder) in (4,5,6) then 2
when extract(month from date_holder) in (7,8,9) then 3
when extract(month from date_holder) in (10,11,12) then 4 else 0 END,
extract(month from date_holder),
to_char(to_date(date_holder),'ww'),
to_char(to_date(date_holder),'w'),
trunc(date_holder,'iw')-1,
trunc(date_holder,'iw')+5,
sysdate ,
to_char(date_holder,'yyyymm'));
date_holder := date_holder +1;
END LOOP;
END;
/
So the basic idea is:
start with the 1.1.<YEAR> date
add one day by the other and insert values as you described
There seems to be an issue on the calendar week, week in month, start and end of week though .... anyway - the approach should be fine. I omitted the correct key calculation as well - best option would be a SEQUENCE.
p.s.: check this demo.

Resources