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

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;

Related

How to make this query in laravel?

I'm trying to make a query in Laravel, but it's not working. I USE POSTGRESQL
select extract(year from fecha_creacion) as anio, extract(month from fecha_creacion) as mes,
sum(case when tipo = 'entrada' then 1 else 0 end )
from documento
group by extract(year from fecha_creacion), extract(month from fecha_creacion)
order by anio, mes;
I also tried the following.
$data = DB::table('documento')
->selectRaw('year from fecha_creacion AS anio, month from fecha_creacion AS mes')
->sum(case when tipo = 'entrada' then 1 else 0 end )
->orderBy(anio, mes, DESC)
->get();
You can use laravel DB::raw() expresssion query.
You have to pass the query in raw function.
reference: https://laravel.com/docs/5.8/queries#raw-expressions

Issue with Case and Extract Function

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;

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

How to group data results by month

I have a script that I wrote that will tell me what our "On Time Delivery" or "OTD" is based on the current month. Essentially it tells us instantly if we have shipped our materials before or on our promise date.
What I am trying to do now is create a new script that will tie this into our GLPERIODS table so that I can show what the "OTD" is for each month of the year at a glance. When I run this new I get the correct period (Jan-Dec) but my OTD calculation is not grouped by period. Instead they are all the same and I think it's an average of all the data in our system.
I will post the script here as well as the results. (edit: I guess I can't post the results as it won't let me post an image) Any help would be greatly appreciated. Thank you and BTW, I am not a programmer, just someone who works on this stuff occasionally to get the data we are after.
Select "month",
OTD
From (Select Round((1 - ("Late" / "All")), 3) As OTD
From (Select Round(Count(V_RELEASES_COMB.ACTUAL_SHIPDATE), 2) As "Late"
From V_RELEASES_COMB,
GLPERIODS
Where To_Char(V_RELEASES_COMB.ACTUAL_SHIPDATE, 'MM/YYYY') =
To_Char(GLPERIODS.START_DATE, 'MM/YYYY') And
V_RELEASES_COMB.ACTUAL_SHIPDATE > V_RELEASES_COMB.PROMISE_DATE And
V_RELEASES_COMB.ITEMNO Is Not Null And V_RELEASES_COMB.CUMM_SHIPPED > 0),
(Select Case
When Round(Count(V_RELEASES_COMB.ACTUAL_SHIPDATE), 2) = 0 Then 1
Else Round(Count(V_RELEASES_COMB.ACTUAL_SHIPDATE), 2) End As "All"
From V_RELEASES_COMB,
GLPERIODS
Where To_Char(V_RELEASES_COMB.ACTUAL_SHIPDATE, 'MM/YYYY') =
To_Char(GLPERIODS.START_DATE, 'MM/YYYY') And V_RELEASES_COMB.ITEMNO Is Not
Null And V_RELEASES_COMB.CUMM_SHIPPED > 0)),
(Select To_Char(GLPERIODS.START_DATE, 'MONTH') As "month"
From GLPERIODS
Where Extract(Year From GLPERIODS.START_DATE) = Extract(Year From SysDate))
Ok, thank you for the help! Here is the edited script with your input added:
Select "month",
OTD
From (Select trunc(g.start_date, 'Month') mth,
round ( 1 - ( count(
case when v.ACTUAL_SHIPDATE > v.PROMISE_DATE And v.ITEMNO Is Not Null
And v.CUMM_SHIPPED > 0 then V.ACTUAL_SHIPDATE end)
/ greatest(Count(
case when v.ITEMNO Is Not Null And v.CUMM_SHIPPED > 0 then V.ACTUAL_SHIPDATE end
), 1) ) , 3) OTD
from glperiods g
left join v_releases_comb v
on trunc(v.ACTUAL_SHIPDATE, 'Month') = trunc(g.start_date, 'Month')
group by trunc(g.start_date, 'Month')),
(Select To_Char(GLPERIODS.START_DATE, 'MONTH') As "month"
From GLPERIODS
Where Extract(Year From GLPERIODS.START_DATE) = Extract(Year From SysDate))
The results look promising but here is what is happening:
Month OTD
January .956
January .875
January .359
January 1
January 1
January 1
February .978
February .562
February .875
February 1
February 1
etc.
this continues for all months.
The above is in a table format but I have no idea how to post a table on this site. I wish I could just upload a pic but it won't let me.
This query should do the job:
SQLFiddle
select to_char(mth, 'Month') "Month", OTD
from (Select trunc(g.start_date, 'Month') mth,
round ( 1 - ( count(
case when v.ACTUAL_SHIPDATE > v.PROMISE_DATE And v.ITEMNO Is Not Null
And v.CUMM_SHIPPED > 0 then V.ACTUAL_SHIPDATE end)
/ greatest(Count(
case when v.ITEMNO Is Not Null And v.CUMM_SHIPPED > 0 then V.ACTUAL_SHIPDATE end
), 1) ) , 3) OTD
from glperiods g
left join v_releases_comb v
on trunc(v.ACTUAL_SHIPDATE, 'Month') = trunc(g.start_date, 'Month')
Where Extract(Year From g.START_DATE) = Extract(Year From SysDate)
group by trunc(g.start_date, 'Month'))
order by mth
Without few examples it's hard to say for sure that it's OK, it would be good to verify with something.
So if something is wrong please edit your post, add some example rows and explain.
Edit:
I think that creating the view may be more comfortable for you:
create or replace view v_monthly_sums as
Select trunc(g.start_date, 'Month') mth,
count(case when v.ACTUAL_SHIPDATE > v.PROMISE_DATE And v.ITEMNO Is Not Null
And v.CUMM_SHIPPED > 0 then V.ACTUAL_SHIPDATE end) d1,
Count(
case when v.ITEMNO Is Not Null And v.CUMM_SHIPPED > 0 then V.ACTUAL_SHIPDATE end
) d2
from glperiods g
left join v_releases_comb v
on trunc(v.ACTUAL_SHIPDATE, 'Month') = trunc(g.start_date, 'Month')
group by trunc(g.start_date, 'Month')
From this view you can select all values (select * from v_monthly_sums), to see what it contains, do any experiments,
but for your main question you can use something like:
select to_char(mth, 'Month') "Month",
case
when d2 = 0 then null
else round(1-d1/d2, 3)
end otd
from v_monthly_sums
where extract(Year From mth) = 2015 -- you can add here: AND D2<>0 to eliminate null rows
order by mth
GLPERIODS - I suspect that this table is not needed at all, not needed in our query/view for sure,
maybe you created it only to store dates for months which interests you.
But maybe I'm wrong and it is used somewhere else. It can by replaced in our view with simple hierarchical subquery,
but for now let's stay with current solution. Please insert one date for each month, I did not make any protections against more dates.
Why did not your query work? - you joined one number, let's say 0,567, produced by two other complicated queries with every day from table GLPERIODS. This is the reason why you got 12 months with the same, invaluable data.

EXTRACT(month FROM date) issue

I have an issue with the EXTRACT function on Oracle and I have no idea what is wrong with the script below. For some reason if I use the AS keyword with the EXTRACT it throws Invalid Identifier when referenced in the GROUP BY sentence. It works if I reference the column by the automatic name, given without the AS keyword.
WITH counted AS(
SELECT UNIT,
STATUS,
SDESC,
COUNT(1) AS cnt,
EXTRACT(month FROM STATUS_DATE) AS statusMonth,
ROW_NUMBER() OVER(PARTITION BY UNIT ORDER BY COUNT(1) DESC) AS rk
FROM ATMSTATUS
WHERE
STATUS_DATE BETWEEN '1-OCT-13' AND '31-OCT-13' AND
STATUS > 0
GROUP BY UNIT, STATUS, SDESC, statusMonth
ORDER BY UNIT, cnt DESC
)
SELECT *
FROM counted
WHERE rk < (10 + 1)
You can't use aliases in GROUP BY clause, you have to use the whole expression instead:
WITH counted AS(
SELECT UNIT,
STATUS,
SDESC,
COUNT(1) AS cnt,
EXTRACT(month FROM STATUS_DATE) AS statusMonth,
ROW_NUMBER() OVER(PARTITION BY UNIT ORDER BY COUNT(1) DESC) AS rk
FROM ATMSTATUS
WHERE
STATUS_DATE BETWEEN '1-OCT-13' AND '31-OCT-13' AND
STATUS > 0
GROUP BY UNIT, STATUS, SDESC, EXTRACT(month FROM STATUS_DATE)
ORDER BY UNIT, cnt DESC
)
SELECT *
FROM counted
WHERE rk < (10 + 1)

Resources