Invalid identifier when using left outer join in Oracle - oracle

I wrote a query with Left outer join in oracle.But I execute the query I get ORA-00904: "b"."GROSS_DISCOUNT_AMOUNT": invalid identifier error.TableB contains net_discount_number and gross_discount_amount columns.
select
a.GSMNO GSMNO,
a.NET_AMOUNT net,
a.GROSS_AMOUNT gross,
sum(b.net_discount_amount) net_discount, sum(b.gross_discount_amount) gross_discount,
a.code code, a.seq_no
from tableA a
LEFT OUTER JOIN
(select id, code, seq_no, sum(gross_amount) gross_amount, sum(net_discount_amount), sum(gross_discount_amount) from tableB
group by id, code, seq_no)
b ON a.id = b.id and NVL(a.code,b.code) = NVL(b.code,-99) and
NVL(a._seq_no,-99) = NVL(b.seq_no,-99)
and a.gross_amount = b.gross_amount
where a.tvNo like '123% and gsmno ='1111111111'
group by
a.GSMNO,
a.NET_AMOUNT,
a.GROSS_AMOUNT,
a.code, a.seq_no

You haven't specified aliases for aggregate sums, it should be like this:
select
a.GSMNO GSMNO,
a.NET_AMOUNT net,
a.GROSS_AMOUNT gross,
sum(b.net_discount_amount) net_discount, sum(b.gross_discount_amount) gross_discount,
a.code code, a.seq_no
from tableA a
LEFT OUTER JOIN
(select id, code, seq_no,
sum(gross_amount) gross_amount,
sum(net_discount_amount) net_discount_amount,
sum(gross_discount_amount) gross_discount_amount
from tableB
group by id, code, seq_no)
b ON a.id = b.id and NVL(a.code,b.code) = NVL(b.code,-99) and
NVL(a._seq_no,-99) = NVL(b.seq_no,-99)
and a.gross_amount = b.gross_amount
where a.tvNo like '123% and gsmno ='1111111111'
group by
a.GSMNO,
a.NET_AMOUNT,
a.GROSS_AMOUNT,
a.code, a.seq_no

Related

PL-SQL how to inner join twice on the same table

I'm trying to make a query that joins a table twice for language purpose.
But SQL Developer always throws an error
Invalid Identifier in the SELECT
when I try to use the ALIAS of my table (table2 is invalid)
SELECT
table1.code Code,
table2.descr DescrFr,
table3.descr_en DescrEn
FROM
main_table table1
INNER JOIN
descr_table table2 ON table1.code = table2.code
AND table2.lang = 'fr'
INNER JOIN
descr_table table3 ON table1.code = table3.code
AND table3.lang = 'en'
I didn't find anything helpful for my case that could teach me what's wrong with my query.
EDIT
Tested asked by user but resulted with this error
Erreur SQL : ORA-00904: "TABLE3"."code" : identificateur non valide
SELECT
table1.code AS Code,
table2.descr AS DescrFr,
table3.descr AS DescrEn
FROM main_table table1
INNER JOIN descr_table table2 ON (table1.code = table2.code)
INNER JOIN descr_table table3 ON (table1.code = table3.code)
WHERE (table2.lang = 'fr' AND table3.lang = 'en');
Answer
The result is a facepalm... the initial query is working.. i was just using the wrong column name in the descr_table...
I don't know the version you are using but I guess you could try SELECT table1.code AS Code,.... And I would prefer not using so much INNER JOIN in your sql query rather would use at least one RIGHT JOIN or LEFT JOIN because you need to have a "main table" which has the highest priority.
AND of course there is something wrong I guess.
so your code would be fine in this way:
SELECT
table1.code AS Code,
table2.descr AS DescrFr,
table3.descr_en AS DescrEn
FROM
main_table AS table1
INNER JOIN
descr_table AS table2 ON (table1.code = table2.code)
INNER JOIN
descr_table table3 ON (table1.code = table3.code)
WHERE
(table2.lang = 'fr' AND table3.lang = 'en')
I'd avoid the double join altogether.
and never use aliases such as table1
This could be...
SELECT
main.Code,
descr.DescrFr,
descr.DescrEn
FROM
main_table main
INNER JOIN
(
SELECT
code,
MAX(CASE WHEN lang = 'fr' THEN descr END) AS DescrFr,
MAX(CASE WHEN lang = 'en' THEN descr END) AS DescrEn
FROM
descr_table
WHERE
lang IN ('fr', 'en')
GROUP BY
code
)
descr
ON descr.code = main.code
(And even then, from your description, you don't even need the outer join as the code exists in the descr_table.)

Query to retrieve rows with no data even if not satisfying the where clause condition in Oracle

I have a query two tables - TableA , TableB
Query :
select a.name, count(b.code)
from tableA a
join tableA b on b.id = a.id
where a.name = ('AA','BB','WWW')
group by a.name;
The data is available only for AA so it displays the result as
AA 5
But i want to display the data as :
AA 5
BB 0
WWW 0
You can collect expected names into separate table/subquery and then perform a left join with your data tables like
with exp_names as (
select 'AA' name from dual
union all
select 'BB' from dual
union all
select 'WWW' from dual
)
select en.name, count(b.code)
from exp_names en
left join tableA a on en.name = a.name
left join tableB b on b.id = a.id
group by en.name;
fiddle

Run native sql query in JPA give difference result vs when run the same query directly in SQL tool

I have a native query like this:
WITH SOURCE_A AS (
SELECT a.ID FROM A a
WHERE a.SOME_THING > 1000
),
SOURCE_B AS (
SELECT b.ID FROM B b
INNER JOIN A a ON a.B_ID = b.ID
WHERE a.ID IN (SELECT * FROM SOURCE_A)
AND call_to_a_procedure(b.SOME_THING) = 1
),
SOURCE_C AS (
SELECT c.ID FROM C c
INNER JOIN B b ON b.C_ID = c.ID
WHERE b.ID IN (SELECTT * FROM SOURCE_B)
AND call_to_a_procedure(c.SOME_THING) = 1
)
SELECT re.CODE FROM RESULT re
INNER JOIN A a ON a.ID = re.ID_A
WHERE a.ID IN (SELECT * FROM SOURCE_A)
UNION
SELECT re.CODE FROM RESULT re
INNER JOIN B b ON b.ID = re.ID_B
WHERE b.ID IN (SELECT * FROM SOURCE_B)
UNION
SELECT re.CODE FROM RESULT re
INNER JOIN C c ON c.ID = re.ID_C
WHERE c.ID IN (SELECT * FROM SOURCE_C)
When I reun this query with query.getResultList() . Only the result of :
SELECT re.CODE FROM RESULT re
INNER JOIN A a ON a.ID = re.ID_A
WHERE a.ID IN (SELECT * FROM SOURCE_A)
is returned. The two UNION are ignored. But if I run the query directly in SQL tool like Oracle SQL developer or DBeaver, I get full UNION result.
JPA just silently ignore the UNION part, no error or exception.
UPDATE: It maybe because the call to call_to_a_procedure didn't work in jpa because if i remove the call to procedure, I can get the expected result.

How count table a data for every data of table a

I have three table A,B,C.
A table:
id,name
B table:
id,a_id,date
C table:
id,b_id,type(value is 0/1)
I want to print all A.name,A.id and C.countingdata by counting C data where C.type=1 using B table which has A table id
Result look like below:
A.id A.name C.countingdata
1 abc 4
2 vfd 2
3 fdg 0
Well, you can first inner join B and C, do the group by and get C.countingdata using count(). Another join on this subquery with B itself to accommodate the a_id
in the result set.
Now, you can do an inner join between A and the above subquery to get your results.
SQL:
select A.id, A.name, derived.countingData
from A
inner join (
select B.id as b_id,B.a_id,sub_data.countingData
from B
inner join (
select B.id,count(B.id) as countingData
from B
inner join C
on B.id = C.b_id
where C.type=1
group by B.id
) sub_data
on B.id = sub_data.id
) derived
on A.id = derived.a_id
You can find query as below:
Select
A.id
,A.name
,COUNT(C.id)
FROM A
JOIN B ON A.id = B.a_id
JOIN C ON B.id = C.b_id ANd C.type = 1
GROUP BY
A.id
,A.name

Getting ORA-00918: column ambiguously defined error on 10g but works in 11g

select distinct p.id,
format_name(p.fname, p.lname,'local000000000000001') full_name,
p.username,
p.person_no,
jobinfo.name,
company.name2,
company.name,
dom.name,
per_mgr.username,
a.name
from cmt_person p
inner join fgt_locale loc on loc.id='local000000000000001'
left outer join tpt_company company on p.company_id = company.id
left outer join tpt_ext_job_type jobinfo on p.jobtype_id = jobinfo.id AND jobinfo.locale_id=loc.id
inner join fgt_domain dom on p.split = dom.id
left outer join fgt_gen gen on gen.id1 = p.id and gen.TYPE = 301 and gen.str2 IS NULL
left outer join fgt_ext_admin_managed_lov a on a.id = gen.id2 and a.locale_id = loc.id
left outer join cmt_person per_mgr on per_mgr.id = p.manager_id
inner join fgt_address a on a.owner_id = p.id
where ( p.terminated_on is null or p.terminated_on >= sysdate)
and( (p.type = 100 and p.split in ('domin000000000000007','domin000000000001107','domin000000000001108','domin000000000001109','domin000000000001104','domin000000000001103','domin000000000001106','domin000000000001105','domin000000000000001','domin000000000001102','domin000000000001110'))
or (p.type = 200 and p.split in ('domin000000000000007','domin000000000001107','domin000000000001108','domin000000000001109','domin000000000001104','domin000000000001103','domin000000000001106','domin000000000001105','domin000000000000001','domin000000000001102','domin000000000001110')) )
AND 1=1
AND lower(p.status) = lower('A')
AND lower(a.country) like lower('USA' || '%')
AND p.type in (decode('1','1',100,'2',200,'0',p.type))
AND p.manager_id in ('emplo000000000034578')
ORDER BY 2,3,4,5,6,7,8,9,10
This is the query I have defined table alias for all tables
Do I need column aliases for following columns for 10g?
jobinfo.name ,
company.name2 ,
company.name ,
dom.name
Two tables share the same alias ("a"): fgt_ext_admin_managed_lov and fgt_address. Change it, as that won't work:
SQL> select a.deptno
2 from dept a, emp a;
select a.deptno
*
ERROR at line 1:
ORA-00918: column ambiguously defined
SQL>
Look at below code :-
left outer join fgt_ext_admin_managed_lov a <<<
..
..
inner join fgt_address a <<<<
You have used same alias name for both tables. Change it to any other alias name.

Resources