Oracle Invalid Identifier (with Inner Join) - oracle

I'm having an "Invalid Identifier" in Oracle because of the "B.username" (username column does exist in USER table). When i remove this, it's working fine. How to resolve this issue? I came from a MySQL background.
SELECT * FROM (SELECT qNA.assignment, qNA.regDate, B.username, (
SELECT DISTINCT NVL(idx, 0)
FROM EK_USERGRADE
WHERE year = (SELECT DISTINCT userGradeNo FROM EK_USER WHERE ID = qNA.userIdx)
) AS userGradeIdx
FROM EK_NEWTESTAPPLICANT qNA
WHERE IDX = :idx ) A
INNER JOIN EK_USER B ON (A.userIdx = B.ID)

Let's try this with a simplified version of your query:
-- test tables
create table NEWTESTAPPLICANT as select 1 useridx from dual ;
create table B as select 1 id, 'name1' username from dual ;
-- query
select *
from (
select B.username
from NEWTESTAPPLICANT qNA
) A join B on A.useridx = B.id ;
-- ORA-00904: "B"."USERNAME": invalid identifier
There's no "username" column in the NEWTESTAPPLICANT table, which causes the error. A LATERAL inline view (examples see here) may do the trick ...
-- query
select
*
from B, lateral (
select B.username
from NEWTESTAPPLICANT qNA
) A ;
-- result
ID USERNAME USERNAME
1 name1 name1
This works with Oracle 12c.

The problem is, that both your virtual table A and users B have the same column name "username". Specify alias in the main select, like "Select A.* , B.* from(...".

Is it ORA-00903?
User is a reserved word are you sure you created this table? Table name cannot be a reserved word.

Related

FOR LOOP Statement in BigQuery

I have data in two tables:
Table activity:
User_ID Event_Time Cmd
AMsySZb9GPcL 1512125190721078 1
AMsySZYQ-lAI 1512118629594674 0
AMsySZZMlPzD 1512125736366076 1
....
Table behaviour:
User_ID Event_Time
AMsySZZFezm 1512145788526664
AMsySZb9GPcL 1512125190721078
AMsySZY5YcTa 1512143509733637
AMsySZYQ-lAI 1512118629594674
AMsySZZMlPzD 1512125736366076
....
User_ID is type STRING, Event_Time is type INTEGER.
Step 1: The basic SELECT statement I am making now is:
SELECT activity.User_ID, activity.Event_Time FROM activity WHERE Cmd=1
Step 2: Then I would like to get data from behaviour table, but only for Users from Step 1 and only where behaviour.Event_Time is before activity.Event_Time.
For example:
From Step 1 I got User_ID='AMsySZb9GPcL' and I need:
SELECT behaviour.User_ID, behaviour.Event_Time
FROM behaviour
WHERE User_ID='AMsySZb9GPcL' AND activity.Event_Time >= behaviour.Event_Time
But the problem is that I have to do the same for every User_ID from Step 1, I am not sure if it is the supported functionality of SQL, but I need something like FOR LOOP.
You don't need FOR LOOP for this - you should think of set based operation when you deal with SQL of any sort - so you can process all your users in one shot using power of JOINs
Below is for BigQuery Standard SQL
#standardSQL
SELECT
activity.User_ID User_ID,
activity.Event_Time activity_Time,
behaviour.Event_Time behaviour_Time
FROM `project.dataset.activity` activity
JOIN `project.dataset.behaviour` behaviour
ON activity.User_ID = behaviour.User_ID
AND activity.Event_Time >= behaviour.Event_Time
WHERE Cmd = 1
You can test / play with above using dummy data from your example:
#standardSQL
WITH `project.dataset.activity` AS (
SELECT 'AMsySZb9GPcL' User_ID, 1512125190721078 Event_Time, 1 Cmd UNION ALL
SELECT 'AMsySZYQ-lAI', 1512118629594674, 0 UNION ALL
SELECT 'AMsySZZMlPzD', 1512125736366076, 1
), `project.dataset.behaviour` AS (
SELECT 'AMsySZZFezm ' User_ID, 1512145788526664 Event_Time UNION ALL
SELECT 'AMsySZb9GPcL', 1512125190721078 UNION ALL
SELECT 'AMsySZY5YcTa', 1512143509733637 UNION ALL
SELECT 'AMsySZYQ-lAI', 1512118629594674 UNION ALL
SELECT 'AMsySZZMlPzD', 1512125736366076
)
SELECT
activity.User_ID User_ID,
activity.Event_Time activity_Time,
behaviour.Event_Time behaviour_Time
FROM `project.dataset.activity` activity
JOIN `project.dataset.behaviour` behaviour
ON activity.User_ID = behaviour.User_ID
AND activity.Event_Time >= behaviour.Event_Time
WHERE Cmd=1

ora 22992 on a LOB field i am not using

I have the following simple oracle query:
select A.field
from table1 A
left join table2#remotedb B on A.id = B.id
Where table B has a BLOB field
It runs fine
If i add a concat to the select:
select A.field||'x'
from table1 A
left join table2#remotedb B on A.id = B.id
I get the following error:
"ora-22992 cannot use lob locators selected from remote tables"
Why adding a concat to a filed which isn't the LOB file is giving me this error?!?
What can i do to avoid it?
check this
with sub1 as
(
select /*+ materialize */ A.field
from table1 A
left join table2#remotedb B on A.id = B.id
)
select field || 'x'
from sub1
I just ran into similar issue. It seems Oracle requires it must be guaranteed any work with clob is avoided at remote side.
Assuming #remotedb is db link to another Oracle db, consider this minimized case:
select dummy from dual; -- works
select to_clob(dummy) from dual; -- works
select dummy from dual#remotedb; -- works
select to_clob(dummy) from dual#remotedb; -- fails - ORA-22992
with m as (select /*+ MATERIALIZE */ dummy from dual#remotedb)
select to_clob(dummy) from m; -- works again, fails without hint
I also tried to find workaround based on forcing computation to local db (select /*+DRIVING_SITE(local)*/ to_clob(r.dummy) from dual local, dual#remotedb r) but with no success.

can i set up an SSRS report where users input parameters to a table

I have an oracle query that uses a created table as part of the code. Every time I need to run a report I delete current data and import the new data I receive. This is one column of id's. I need to create a report on SSRS in which the user can input this data into said table as a parameter. I have designed a simple report that they can enter some of the id's into a parameter, but there may be times when they need to enter in a few thousand id's, and the report already runs long. Here is what the SSRS code currently says:
select distinct n.id, n.notes
from notes n
join (
select max(seq_num) as seqnum, id from notes group by id) maxresults
on n.id = maxresults.ID
where n.seq_num = maxresults.seqnum
and n.id in (#MyParam)
Is there a way to have MyParam insert data into a table I would join called My_ID, joining as Join My_Id id on n.id = id.id
I do not have permissions to create functions or procedures in the database.
Thank you
You may try the trick with MATERIALIZE hint which normally forces Oracle to create a temporary table :
WITH cte1 AS
( SELECT /*+ MATERIALIZE */ 1 as id FROM DUAL
UNION ALL
SELECT 2 DUAL
)
SELECT a.*
FROM table1 a
INNER JOIN cte1 b ON b.id = a.id

PostgreSQL and filtered recursive query

There is an ability to query tree in Oracle with clauses CONNECT BY and START WITH.
For example:
SELECT RPAD (' ', (LEVEL - 1) * 4) || node_name AS node, LEVEL
FROM hierarchy
START WITH NVL (pig_ear_id, 0) = 0
CONNECT BY PRIOR id = pig_ear_id;
The query result can be simply filtered to show the only nodes which accepted by filter predicate or located on the path to root:
SELECT RPAD (' ', (LEVEL - 1) * 4) || node_name AS node, LEVEL
FROM hierarchy
START WITH NVL (pig_ear_id, 0) = 0
CONNECT BY PRIOR id = pig_ear_id AND id IN (
SELECT id
FROM hierarchy
START WITH node_name = 'some-pattern'
CONNECT BY PRIOR pig_ear_id = id
);
A similar select in PostgreSQL will be built with clause WITH RECURSIVE .... As I understand one with-query can not be included in other with-query to get same filtered result as Oracle allows.
How to rewrite the second select in PostgreSQL?..
As I understand one with-query can not be included in other with-query
Of course you can, just write one after the other:
with recursive valid_nodes as (
-- this is the inner "CONNECT BY" query from your example
select id
from hierarchy
where node_name = 'some-pattern'
union all
select c.id
from hierarchy c
join valid_nodes p on c.id = p.pig_ear_id
), final_tree as (
-- this is outer query from your example
select node_name as node, 1 as level
from hierarchy
where NVL (pig_ear_id, 0) = 0
union all
select c.node_name, p.level + 1
from hierarchy c
join final_tree p on p.id = c.pig_ear_id
where id in (select id from valid_nodes) -- and here we re-use the previous CTE
)
select rpad(node, level - 1)||node, level
from final_tree;
Note the recursive keyword only needs to be stated at the beginning. Regardless on how many recursive CTEs you have (but you need to have at least one in the CTE chain, if you use it).
If you have a with query that is calling some function and that function in turn has a with query,
then it allows us and not raise any error...in that way we still able to have nested with query.
so typically i created a query using with clause. see the first query below.
It has in clause which has select query that is selecting records returned by the functions(my_function).
and the function has another hierarchical with query.
Also i do not know what you want to return from your query.so change query as u need.This is just the way to achieve required structure.
Below is the syntax for sql server.Change appropriately for any other database.
with alias_list
(
pig_ear_id,
node_name,
id
) as (
select pig_ear_id, node_name, id
from hierarchy
where pig_ear_id = ?
union all
select b.pig_ear_id, node_name, id
from alias_list a, hierarchy b
where a.pig_ear_id = b.id
and id in (select id from my_function('some-pattern')))
select * from alias_list;
==============================================================
create function my_function(#node_name varchar(40))
returns #temptable table
(
id varchar(40)
)
as
begin
with alias_list
(
pig_ear_id,
node_name,
id
) as (
select pig_ear_id, node_name, id
from hierarchy
where node_name = ?
union all
select b.pig_ear_id, node_name, id
from alias_list a, hierarchy b
where a.id = b.pig_ear_id)
insert into #temptable select * from alias_list;
return
end
================================================================

Why can't hive recognize alias named in select part?

Here's the scenario: When I invoke hql as follows, it tells me that it cannot find alias for u1.
hive> select user as u1, url as u2 from rank_test where u1 != "";
FAILED: SemanticException [Error 10004]: Line 1:50 Invalid table alias or column reference 'u1': (possible column names are: user, url)
This problem is the same as when I try to use count(*) as cnt. Could anyone give me some hint on how to use alias in where clause? Thanks a lot!
hive> select user, count(*) as cnt from rank_test where cnt >= 2 group by user;
FAILED: ParseException line 1:58 missing EOF at 'where' near 'user'
The where clause is evaluated before the select clause, which is why you can't refer to select aliases in your where clause.
You can however refer to aliases from a derived table.
select * from (
select user as u1, url as u2 from rank_test
) t1 where u1 <> "";
select * from (
select user, count(*) as cnt from rank_test group by user
) t1 where cnt >= 2;
Side note: a more efficient way to write the last query would be
select user, count(*) as cnt from rank_test group by user
having count(*) >= 2
If I remember correctly, you can refer to the alias in having i.e. having cnt >= 2
I was able to use Alias in my Hive select statement using backtick symbol ``.
SELECT COL_01 AS `Column_A`;
The above solution worked for Hive version 1.2.1.
reference link

Resources