ORA-00907: missing right parenthesis when creating a table - oracle

I have the below query that works fine and produces the correct result
select id, sum(item_stock)
from seller
group by id
order by id ASC;
When I try to create a table with the query above like this
CREATE TABLE total_stock
AS (
select id, sum(item_stock)
from seller
group by id
order by id ASC );
I get the following error
SQL Error: ORA-00907: missing right parenthesis
Any help on why this isn't working would be greatly appreciated

Your problem is caused by the clause ORDER BY.
You have to:
Add an alias to your "sum" field
Create another subquery in order to "remove" the ORDER BY clause
CREATE TABLE total_stock
AS (
select id, item_stock
from (
select id, sum(item_stock) as item_stock
from seller
group by id
order by id ASC
)
)

Related

Getting error ORA-00904: "ID_NAME_COLL_TYPE": invalid identifier while creating view with oracle object

I am reading book Practical Oracle SQL. In this book in chapter 2 Author is creating a view with User defined types. Here are the queries
create or replace type id_name_type as object (
id integer,
name varchar2(20 char)
);
/
create or replace type id_name_coll_type as table of id_name_type;
/
create or replace view customer_order_products_obj
as
select
customer_id,
max(customer_name) as customer_name,
cast(
collect(
id_name_type(product_id, product_name)
order by product_id
) as id_name_coll_type
) as product_coll
from customer_order_products
group by customer_id, id_name_coll_type;
But when I tried to run the view query then I got the error ORA-00904: "ID_NAME_COLL_TYPE": invalid identifier Then I narrow down the query and just run the following query. Just run select and remove the name from group by.
select
customer_id,
max(customer_name) as customer_name,
cast(
collect(
id_name_type(product_id, product_name)
order by product_id
) as id_name_coll_type
) as product_coll
from customer_order_products
group by customer_id;
The above query gives the following results
So what is wrong with the group by customer_id, id_name_coll_type;? Why in this case I am getting "ID_NAME_COLL_TYPE": invalid identifier. As it is a book example that's why I thought it should work as it is ? How view will create ?
Thanks
id_name_coll_type is an identifier for a data type and not an identifier for a column; you must aggregate by columns.
As it is a book example that's why I thought it should work as it is?
Books can contain mistakes; you should check to see if there is an errata for the book that may contain a correction or if you have the latest version of the book. If not, you can e-mail the author/publisher and let them know of the mistake.
How view will create?
Do exactly what you did and do not include the id_name_coll_type identifier in the GROUP BY clause. You do not need to add the collection to the GROUP BY clause as COLLECT is an aggregation function.
db<>fiddle here

How to fix hive code for counting a column and group by another column?

There are 3 columns in my hive data (user, gender, rating). now, I want to count number of user_id, gender wise. I have written hive code as
select user_id, gender, count(*) from u_user group by user_id;
but the error that I have got is
SemanticException [Error 10025]: Line 1:16 Expression not in GROUP BY
key 'gender'
How to fix this?
Well, the keys you group by should be the same with the keys in the select. As below:
select user_id,gender,count(1) from u_user group by user_id,gender;
And if you want to count user_id of each gender type , you can write like this:
select gender,count(distinct user_id) from u_user group by gender;

How to min function without group by in Hive

Consider the following hive query.
SELECT
id,
name,
min(from_unixtime(unix_timestamp(), 'yyyy_MM_dd_HH_mm_ss')) as SYSDATE
FROM tablename
The reason why I used min function is that I wanted the same SYSDATE in all of my records. If I don't add min here, multiple SYSDATE may appear.
I got an error running the query:
An exception was caught.
Error while compiling statement: FAILED: SemanticException [Error 10025]: Line 3:4 Expression not in GROUP BY key 'name'
So I added GROUP BY in my query and it worked.
SELECT
id,
name,
min(from_unixtime(unix_timestamp(), 'yyyy_MM_dd_HH_mm_ss')) as SYSDATE
FROM tablename
GROUP BY id, name
But what if I have twenty or more columns? Isn't it inconvenient to add them all to GROUP BY? And why should I add GROUP BY here? I just want a consistent SYSDATE all across the records. Is there any other way to make it work?
if you do not have any concern about performance, try to use window function to calculate min:
SELECT
id ,
name ,
min(from_unixtime(unix_timestamp(), 'yyyy_MM_dd_HH_mm_ss')) over(partition by 1) as SYSDATE
FROM tablename

Oracle: Selecting * and aggregate column

Is it possible to select fields using the method below?
SELECT *, count(FIELD) FROM TABLE GROUP BY TABLE
I get the following error
ORA-00923: FROM keyword not found where expected
00923. 00000 - "FROM keyword not found where expected"
*Cause:
*Action:
Error at Line: 1 Column: 9
Is it a syntax error or do you have to explicitly define each column rather than using *?
You can't use * and other columns. If you use an alias, then you can:
SELECT t.*
, count(FIELD)
FROM TABLE t
Also, your GROUP BY TABLE is wrong. You can't group by the table name, you must specify some columns, like this:
SELECT t.customer
, count(FIELD)
FROM TABLE t
GROUP BY t.customer
The columns that are selected in the field should be
an expression used as one of the group by criteria , or
an aggregate function , or
a literal value
For this, you need to indicate the fields you needed and should fit in the following criteria mentioned above.
SELECT FIELD1,FIELD2, COUNT(*) FROM TABLE1 GROUP BY FIELD1, FIELD2
If you insist to use the logic of your query, the use of subquery should be helpful.
For example,
SELECT * FROM TABLE1 T1 INNER JOIN (SELECT FIELD1, COUNT(FIELD1) AS [CountOfFIELD1] FROM TABLE1 T2 GROUP BY FIELD1)T3 ON T1.FIELD1=T3.FIELD1
Instead of * you need to give the column names:
SELECT a, b, COUNT(FIELD)
FROM TABLE
GROUP BY a, b;

INSERT INTO statement with SELECT... IN error

Well, i need to add a row in user_badges for each person who had correctly respond to a poll. The
"select user_id from room_poll_results........" is working fine alone, but as soon as i try to use it in my INSERT INTO statement, it gives back an error:
"[Err] 1054 - Unknown column 'user_id' in 'IN/ALL/ANY subquery'"
I don't know where it's coming from...
INSERT INTO user_badges (user_id,PPO) SELECT user_id IN
(SELECT user_id FROM room_poll_results
WHERE user_id in (select user_id from room_poll_results
where answer_text='3' AND question_id='3') AND user_id in
(select user_id from room_poll_results where answer_text='2' AND question_id='4'));
It's telling you that there's no column called user_id in room_poll_results. Change that column name (in the subselects) to whatever is the appropriate field in the table. (You'd want to post the full schema for a more specific response.)
Whenever you get errors as "[Err] 1054 - Unknown column 'user_id' in 'IN/ALL/ANY subquery'" just read it to mean that a COLUMN with the give name in parenthesis does not exist in your query.
To debug this, since you are have sub-queries, run each query independently then see their results. That will help you know what table has the missing column. Once you've got it then you can create the column and then unite your sub-queries and that's it!
I assume user_badges table has a column user_id. Your first IN should be replaced by FROM. So, I've slightly modified your query as below:
INSERT INTO user_badges (user_id, PPO)
SELECT user_id FROM
(
SELECT user_id FROM room_poll_results
WHERE user_id in
(
select user_id from room_poll_results
where answer_text='3' AND question_id='3'
) AS U
AND user_id in
(
select user_id from room_poll_results
where answer_text='2' AND question_id='4'
) AS U
) AS U;

Resources