showing record from table year wise - oracle

select station_id,count(case_id) from emer_complaint group by station_id
Above query returning the correct result. But, when i'm trying this query for showing the record in year wise. Then it shows the error ORA-00904: "YEAR": invalid identifier
select year(date_time)
,count(case_id)
from emer_complaint
group by year(date_time);
the datatype of date_time is Timestamp.
Thanks in advance.!!

select to_char(date_time, 'YYYY'), count(case_id)
from emer_complaint
group by to_char(date_time, 'YYYY');

Related

Trying to limit the results of a group by query to a range of dates

I'm trying to limit a query's results to the latest 14 distinct PROCESS_DATE dates. To do this, I have used a CTE expression to retrieve the latest and earliest dates for the date range
With these 2 values, I would like to plug them into a group by statement so that I will get results between the two dates
But I am getting this error when I run the query in Oracle
ORA-00904: "MAX_PROCESS_DATE": invalid identifier
00904. 00000 - "%s: invalid identifier"
*Cause:
*Action:
Error at Line: 24 Column: 60
Line: 24 Column: 60 is the WHERE PROCESS_DATE >= MIN_PROCESS_DATE AND .... MAX_PROCESS_DATE part of the Group By statement
If this is a wrong way to go about this task, please pardon me and suggest a better query. If it's on the right track, how would I fix it so it will run successfully?
WITH cteQUERYRANGE AS
(
SELECT MAX(PROCESS_DATE) AS MAX_PROCESS_DATE, MIN(PROCESS_DATE) AS MIN_PROCESS_DATE FROM
(
SELECT DISTINCT PROCESS_DATE FROM PAYMENTS
ORDER BY PROCESS_DATE DESC
FETCH FIRST 14 ROWS ONLY
)
)
SELECT PROGRAM_CODE AS PROGRAM, BWE_DATE AS "BWE DATE", PROCESS_DATE AS "PROCESSED DATE", GROSS_AMOUNT AS ENTITLEMENTS, FPUC, LWA
FROM PAYMENTS
WHERE PROCESS_DATE >= MIN_PROCESS_DATE AND PROCESS_DATE <= MAX_PROCESS_DATE
GROUP BY PROGRAM_CODE, BWE_DATE, PROCESS_DATE, GROSS_AMOUNT, FPUC, LWA
ORDER BY PROCESS_DATE DESC;
To me, it looks like this (see 3 comments within code):
WITH ctequeryrange AS(SELECT MAX(process_date) AS max_process_date,
MIN(process_date) AS min_process_date
FROM(SELECT DISTINCT process_date
FROM payments
ORDER BY process_date DESC
FETCH FIRST 14 ROWS ONLY)
)
SELECT DISTINCT program_code AS program, --> distinct
bwe_date AS "BWE DATE",
process_date AS "PROCESSED DATE",
gross_amount AS entitlements,
fpuc,
lwa
FROM payments cross join ctequeryrange --> cross join
WHERE process_date >= min_process_date
AND process_date <= max_process_date
ORDER BY process_date DESC; --> no group by
if you want to use columns from a CTE, you have to "reference" it, somehow. As it returns only one row, cross join is safe
as there are no aggregates in your query, no need to GROUP BY - DISTINCT would do
Though, your fetch first 14 rows won't result in 14 rows (if that was your intention) as CTE itself returns only one row.

ORACLE APEX-ORA 01722 Invalid Number ERROR

I don't understand , why I am taking this error.
SELECT
to_char(view_date, 'Month') MONAT ,
COUNT(*) AS countx
FROM
AXY_TABLE
GROUP BY
to_char(view_date,'Month')
ORDER BY
to_char(view_date, 'Month'),
COUNT(*) desc;
When I execute this Query for a Interactive Report, it throws ORA-01722 Error. This Query run not only correctly in SQL developer but also as Classic Report correctly. When I changed the type to Interactive Report, throws it again the same error.
What should I do ?
Thanks a lot in advance.
Is the problem the ORDER BY clause? Try removing the aggregation from it:
SELECT
to_char(view_date, 'Month') MONAT ,
COUNT(*) AS countx
FROM
AXY_TABLE
GROUP BY
to_char(view_date,'Month')
ORDER BY
to_char(view_date, 'Month'),
2 desc;
This orders by the position of the second column of the projection. However, it is strictly unnecessary, as your result set will conatin only one row per MONTH, so you only need to sort by that.

Oracle date formatting error - ORA-00933: SQL command not properly ended

I am trying to execute a simple query (ORACLE DB) to display two date columns (START_TIME & END_TIME) along with total counts along with percentage and filtered by a month followed by year the data type defined in the for the two date fields in db as date, i am trying to display the data in the below format
sample data no time stamp
start_time - 01.12.2020
end_time - 02.12.2020
Query
SELECT
to_char(cast(START_TIME as date),'YYYY') as START_BY_YEAR ,
to_char(cast(END_TIME as date),'YYYY') as END_BY_YEAR ,
to_char(cast(START_TIME as date),'MM.YYYY')as START_BY_MONTH,
to_char(cast(END_TIME as date),'MM.YYYY') as END_BY_MONTH,
to_char(cast(START_TIME as date),'DD.MM.YYYY') as START_BY_DAY,
to_char(cast(END_TIME as date),'DD.MM.YYYY') as END_BY_DAY,
COUNT(*) as count,
round(100*ratio_to_report(count(*)) over (), 4) percentage
FROM SCHEMA_NAME.TABLE_NAME
WHERE to_char(cast(START_TIME as date),'MM.YYYY')='12.2020'
and to_char(cast(END_TIME as date),'MM.YYYY')='12.2020'
GROUP BY
START_BY_YEAR,
END_BY_YEAR,
START_BY_MONTH,
END_BY_MONTH,
START_BY_DAY,
END_BY_DAY
order by
START_BY_YEAR desc,
END_BY_YEAR desc,
START_BY_MONTH desc,
END_BY_MONTH desc,
START_BY_DAY desc,
END_BY_DAY desc
I am getting error message
ORA-00904: "END_BY_DAY": invalid identifier
00000 - "%s: invalid identifier"
*Cause:
*Action:
Error at Line: 19 Column: 1
where exactly i am getting error is not clear
expected result set
START_BY_YEAR END_BY_YEAR START_BY_MONTH END_BY_MONTH START_BY_DAY END_BY_DAY
2012 2012 12.2012 12.2012 01.12.2020 02.12.2020
Please note i have expanded the code for easily readable purpose.
Suggestion ?
To solve the error, you have to remove the aliases from the GROUP BY clause.
Also, if your table has date columns, you don't need CASTs and the query can be re-wrtten as:
SELECT
to_char(START_TIME,'YYYY') START_BY_YEAR ,
to_char(END_TIME,'YYYY') END_BY_YEAR ,
to_char(START_TIME,'MM.YYYY') START_BY_MONTH,
to_char(END_TIME,'MM.YYYY') END_BY_MONTH,
to_char(START_TIME,'DD.MM.YYYY') START_BY_DAY,
to_char(END_TIME,'DD.MM.YYYY') END_BY_DAY,
COUNT(*) as count,
round(100*ratio_to_report(count(*)) over (), 4) percentage
FROM TABLE_NAME
WHERE to_char(START_TIME,'MM.YYYY')='12.2020'
and to_char(END_TIME,'MM.YYYY')='12.2020'
GROUP BY
to_char(START_TIME,'YYYY') ,
to_char(END_TIME,'YYYY') ,
to_char(START_TIME,'MM.YYYY') ,
to_char(END_TIME,'MM.YYYY') ,
to_char(START_TIME,'DD.MM.YYYY') ,
to_char(END_TIME,'DD.MM.YYYY')
order by
START_BY_YEAR desc,
END_BY_YEAR desc,
START_BY_MONTH desc,
END_BY_MONTH desc,
START_BY_DAY desc,
END_BY_DAY desc
With a table like this:
create table table_name as
(
select date '2020-12-01' start_time,
date '2020-12-02' end_time
from dual
);
The query gives:
START_BY_YEA END_BY_YEAR START_BY_MON END_BY_MONTH START_BY_DAY END_BY_DAY COUNT PERCENTAGE
------------ ------------ ------------ ------------ ------------ ------------ ----- ----------
2020 2020 12.2020 12.2020 01.12.2020 02.12.2020 1 100
1 row selected.
First check the partial result of:
select cast(END_TIME as date),'DD.MM.YYYY') as END_BY_DAY
FROM SCHEMA_NAME.TABLE_NAME
from the results you can learn about the NLS format of your machin and wrap it with custom to_char format.

Oracle: extract year from date in listagg

I have a table with date column and would like to obtain a string with distinct years:
ID DATA
1 01/01/2010
2 02/01/2010
3 01/03/2011
4 03/01/2014
5 05/02/2014
From the above table and using listagg I want to get the years
2010
2011
2014
But when I run the following query:
SELECT LISTAGG(EXTRACT(year from data),',')
WITHIN GROUP (ORDER BY data)
FROM (SELECT distinct EXTRACT(year from data)
FROM t_teste)
I get the following error
ORA-00904: "DATA": invalid identifier
Any idea what I'm doing wrong?
You're using a subquery that is not specifying an alias for your extracted year value, and the data column from your table is no longer visible - as it is only in scope inside the subquery.
You can add a column alias and then refer to that directly in the outer query, without needing another extract:
select listagg(anno, ',') within group (order by anno)
from (
select distinct extract(year from data) as anno
from t_teste
);
LISTAGG(ANNO,',')WITHINGROUP(ORDERBYANNO)
-----------------------------------------
2010,2011,2014

"BETWEEN" SQL Keyword for Oracle Dates -- Getting an error in Oracle

I have dates in this format in my database "01-APR-12" and the column is a DATE type.
My SQL statement looks like this:
SELECT DISTINCT c.customerno, c.lname, c.fname
FROM customer c, sales s
WHERE c.customerno = s.customerno AND s.salestype = 1
AND (s.salesdate BETWEEN '01-APR-12' AND '31-APR-12');
When I try to do it that way, I get this error -- ORA-01839: date not valid for month specified.
Can I even use the BETWEEN keyword with how the date is setup in the database?
If not, is there another way I can get the output of data that is in that date range without having to fix the data in the database?
Thanks!
April has 30 days not 31.
Change
SELECT DISTINCT c.customerno, c.lname, c.fname
FROM customer c, sales s
WHERE c.customerno = s.customerno AND s.salestype = 1
AND (s.salesdate BETWEEN '01-APR-12' AND '31-APR-12');
to
SELECT DISTINCT c.customerno, c.lname, c.fname
FROM customer c, sales s
WHERE c.customerno = s.customerno AND s.salestype = 1
AND (s.salesdate BETWEEN '01-APR-12' AND '30-APR-12');
and you should be good to go.
In case the dates you are checking for range from 1st day of a month to the last day of a month then you may modify the query to avoid the case where you have to explicitly check the LAST day of the month
SELECT DISTINCT c.customerno, c.lname, c.fname
FROM customer c, sales s
WHERE c.customerno = s.customerno
AND s.salestype = 1 AND (s.salesdate BETWEEN '01-APR-12' AND LAST_DAY(TO_DATE('APR-12', 'MON-YY'));
The LAST_DAY function will provide the last day of the month.
The other answers are missing out on something important and will not return the correct results. Dates have date and time components. If your salesdate column is in fact a date that includes time, you will miss out on any sales that happened on April 30 unless they occurred exactly at midnight.
Here's an example:
create table date_temp (temp date);
insert into date_temp values(to_date('01-APR-2014 15:12:00', 'DD-MON-YYYY HH24:MI:SS'));
insert into date_temp values(to_date('30-APR-2014 15:12:00', 'DD-MON-YYYY HH24:MI:SS'));
table DATE_TEMP created.
1 rows inserted.
1 rows inserted.
select * from date_temp where temp between '01-APR-2014' and '30-APR-2014';
Query Result: 01-APR-14
If you want to get all records from April that includes those with time-components in the date fields, you should use the first day of the next month as the second side of the between clause:
select * from date_temp where temp between '01-APR-2014' and '01-MAY-2014';
01-APR-14
30-APR-14

Resources