Oracle subquery invalid identifier - sql

I can not figure it out what is wrong with this query:
select * from inv_srv_inst inst,
(select srvc.li_srv_cat_id from inv_li_srv_cat_srv srvc where srvc.srv_id = inst.service_id) li_srv_cat_id
where id in (37336558,37343286)
Error message:
ORA-00904: "INST"."SERVICE_ID": invalid identifier
00904. 00000 - "%s: invalid identifier"

ORA-00904: "INST"."SERVICE_ID": invalid identifier
You get this error because INV_SRV_INST is not in scope of the inline view. If you're using 12c or later you can work around this using the LATERAL keyword, which allows us to push predicates into subqueries:
select *
from inv_srv_inst inst,
lateral (select srvc.li_srv_cat_id
from inv_li_srv_cat_srv srvc
where srvc.srv_id = inst.service_id) li_srv_cat_id
where id in (37336558,37343286)
Although it must be asked, why did you choose an inline view rather than just joining the two tables?
select inst.*
,srvc.li_srv_cat_id
from inv_srv_inst inst
inner join inv_li_srv_cat_srv srvc
on srvc.srv_id = inst.service_id
where inst.id in (37336558,37343286)
Here is a demo on db<>fiddle.

Never use commas in the FROM clause.
In your case, you can express this using a lateral join or a correlated subquery -- assuming there is only one match.
select *
from inv_srv_inst inst cross join lateral
(select srvc.li_srv_cat_id
from inv_li_srv_cat_srv srvc
where srvc.srv_id = inst.service_id
) li_srv_cat_id
where inst.id in (37336558, 37343286);
Lateral joins are very handy. They are like correlated subqueries but they can return multiple columns and multiple rows.

Related

Outer join for Alias name and column name -Oracle

I had a working sample query earlier in my code as mentioned below.
SELECT DISTINCT
nombre_aplicacion,
APLICACION,
NOMBRE_APLCODE,
DESCRIPCION,
AREAFUNC
FROM (
select **CODAPLICATION nombre_aplicacion**,
APLICACION,
NOMBRE_APLCODE,
DESCRPTION,
AREAFUNC
from admin.VW_APLICACIONES#dblink,
admin.VW_PRODUCTOS#dblink
where **nombre_aplicacion (+) = CODAPLICATION**
)
WHERE 1=1
ORDER BY nombre_aplicacion ASC;
When I try similar type of query with different tables I was getting error as invalid ORA-00904: "NOMBRE_APLICACION": invalid identifier.
If I remove nombre_aplicacion (+) = CODAPLICATION in where condition query is fetching the result. Can any one suggest why I was facing error as its working earlier with sample query and I was getting error? Is this join is valid?
The query is not valid as:
In the inner sub-query you select areafunc and in the outer query you use area which does not appear in the inner sub-query so will not be available.
In the inner sub-query, you define CODAPLICATION to have the alias nombre_aplicacion and then you try to use that alias in the WHERE clause as a join condition; that will not work.
You have not described which column belongs to which table but you want something like:
SELECT DISTINCT
a.codaplication AS nombre_aplicacion,
a.aplicacion,
a.nombre_aplcode,
p.descrption,
p.areafunc
from APLICACIONES a
LEFT OUTER JOIN PRODUCTOS p
ON (a.primary_key_column = p.foreign_key_column)
ORDER BY nombre_aplicacion ASC;
Note: you are going to have to correct the code to give the correct table aliases for each column and give the correct columns for the join condition.

trying to create a view by joining two tables

I am trying to run the following code:
create or replace view StoreContactPurchaseHistoryView AS
select
STORE.StoreName,
StoreContactAndPhone(contact,phone),
PURCHASE_ITEM.PurchaseItemID,
PURCHASE_ITEM.PurchaseDate,
PURCHASE_ITEM.ItemDescription,
PURCHASE_ITEM.PriceUSD
from
store,
purchase_item
left join purchase_item on purchase_item.storeid=store.storeid
;
I keep getting this error:
Error report -
ORA-00904: "STORE"."STOREID": invalid identifier
00000 - "%s: invalid identifier"
Never use commas in the FROM clause. Always use proper, explicit, standard, readable JOIN syntax.
That said, you want something like:
select s.StoreName, StoreContactAndPhone(contact, phone) as col,
pi.PurchaseItemID, pi.PurchaseDate,
pi.ItemDescription, pi.PriceUSD
from store s join
purchase_item pi
on pi.storeid = s.storeid;
Note that I also added table aliases so the query is easier to write and to read.
You are mixing explicit and implicit joins, and seem to need only one join:
create or replace view StoreContactPurchaseHistoryView AS
select
s.StoreName,
StoreContactAndPhone(contact,phone),
p.PurchaseItemID,
p.PurchaseDate,
p.ItemDescription,
p.PriceUSD
from
store s
left join purchase_item p on p.storeid = s.storeid
;
I used table aliases to shorten the query.
Side note: it is unclear what expression StoreContactAndPhone(contact,phone) actually refers to; I left it as-is in the query.
Change it to this:
create or replace view StoreContactPurchaseHistoryView AS
select
STORE.StoreName,
StoreContactAndPhone(contact,phone),
PURCHASE_ITEM.PurchaseItemID,
PURCHASE_ITEM.PurchaseDate,
PURCHASE_ITEM.ItemDescription,
PURCHASE_ITEM.PriceUSD
from
store
left join purchase_item on purchase_item.storeid=store.storeid
;

ORA-00936: missing expression distinct on oracle

i am using oracle 10g plsql,
my query is:
select DISTINCT ON("Rental"."pkRentalId") "pkRentalId",
to_number("Reservation"."ReservationNo") "ReservationNo",
to_char("Rental"."RentalNo") "RentalNo",
to_char(segmentTable."Text"||'-'||rateTypeTable."Text") "RateType",
to_char("Debtor"."DebtorName") "DebtorName",
to_char("Rates"."RateName") "RateName",
to_char("Renter"."FirstName"||' '||"Renter"."LastName") "Renter",
to_date("Rates"."ValidFrom") "ValidFrom",
to_date("Rates"."ValidTo") "ValidTo",
round(to_number(to_number("ReservationDuration"."ExpectedCheckinDateTime"-"ReservationDuration"."DispatchDateTime") *to_number("Rates"."UnitRate")),2) "RentalAmount",
to_number("Deductions"."Amount") "Deduction",
to_number("Billing"."DiscountAmount") "Discount"
from "Reservation"
inner join "Rental" on "Rental"."pkRentalId"="Reservation"."fkRentalId"
inner join "Rates" on "Rates"."pkRateId"="Reservation"."fkRateId"
inner join "Renter" on "Renter"."fkReservationId"="Reservation"."pkReservationId"
inner join "Billing" on "Billing"."pkBillingId"="Reservation"."fkBillingId"
inner join "Deductions" on "Deductions"."fkRentalId"="Rental"."pkRentalId"
inner join "Debtor" on "Debtor"."pkDebtorId"="Rates"."fkDebtorId"
inner join "EnumerationValue" segmentTable on segmentTable."pkEnumerationValueId"="Reservation"."fkSegmentId"
inner join "EnumerationValue" rateTypeTable on rateTypeTable."pkEnumerationValueId"="Reservation"."fkRateTypeId"
inner join "ReservationDuration" on "ReservationDuration"."pkDurationLocationId"="Reservation"."fkDurationId"
where "Reservation"."IsDeleted"='N'
it is returning me :
ORA-00936: missing expression
00936. 00000 - "missing expression"
*Cause:
*Action:
Error at Line: 4 Column: 17
What is the correct format of distinct on in oracle pl/sql? I want to return all the distinct "pkRentalId" values and the maximum value for all the other columns.
If you want the maximum value for each of the other columns, you'd need to do a GROUP BY, not a DISTINCT with the max aggregate function on all the other columns.
select "Rental"."pkRentalId",
max(to_number("Reservation"."ReservationNo")) "ReservationNo",
max(to_char("Rental"."RentalNo")) "RentalNo",
max(to_char(segmentTable."Text"||'-'||rateTypeTable."Text")) "RateType",
max(to_char("Debtor"."DebtorName")) "DebtorName",
max(to_char("Rates"."RateName")) "RateName",
max(to_char("Renter"."FirstName"||' '||"Renter"."LastName")) "Renter",
max(to_date("Rates"."ValidFrom")) "ValidFrom",
max(to_date("Rates"."ValidTo")) "ValidTo",
max(round(to_number(to_number("ReservationDuration"."ExpectedCheckinDateTime"-"ReservationDuration"."DispatchDateTime") *to_number("Rates"."UnitRate")),2)) "RentalAmount",
max(to_number("Deductions"."Amount")) "Deduction",
max(to_number("Billing"."DiscountAmount")) "Discount"
from ...
where ...
group by "Rental"."pkRentalId"
Now, from a requirements standpoint, given the query you have, it seems unusual to want to get the maximum value for all the other columns. That's going to mix data from multiple rows together in a way that doesn't seem to make sense to me.
The distinct on operator from Postgres usually translates to using the window function row_number() where the "distinct" columns are used for the partition by part and the order by is used to select the row you want:
select *
from (
select
row_number() over partition by ("Rental"."pkRentalId" order by "Reservation"."ReservationNo") as rn,
... other columns
from "Reservation"
... joins
where "Reservation"."IsDeleted"='N'
)
where rn = 1
By changing the order by in the window definition you can pick which row you want ("first", "last", "third").
The difference to the solution using max() is that it will preserve the values that belong together in one row.

sql not throwing invalid identifier

I am asking this question because I am not getting an error where I expect there should be an error.
Please help me understand under what circumstances this is possible. I have a query:
select foracid,acct_name, schm_code, schm_type from tbaadm.gam where
acid in(select acid from tbaadm.iar);
This query is returning results without throwing any error. I expect invalid identifier
because the table tbaadm.iar does NOT have a field acid.
When I run:
select acid from tbaadm.iar;
I get:
ORA-00904: "ACID": invalid identifier
00904. 00000 - "%s: invalid identifier"
*Cause:
*Action:
Error at Line: 772 Column: 8
I am using sqldeveloper and oracle 10g. It is kind of Strange to me. Worth to mention though is that there is a field in tbaadm.iar that is an id and so the right Query Should be:
select foracid,acct_name, schm_code, schm_type from tbaadm.gam where
acid in(select entity_id from tbaadm.iar);
What is going on here?
A subquery that's used in an IN clause can reference columns from the outer query, because this is necessary in correlated subqueries. So your WHERE clause is equivalent to:
WHERE acid IN (SELECT tbaadm.gam.acid FROM tbaadm.iar)
An example of a correlated subquery that shows why this is necessary is:
SELECT *
FROM outer_table
WHERE somefield = (SELECT someotherfield
FROM inner_table
WHERE inner_table.id = outer_table.inner_id)
This is the more common use, where the field from the outer table is used in a WHERE clause of the subquery. But SQL isn't picky about where the field from the outer query is used. It can be used anywhere in the subquery that an expression is permitted, which includes the SELECT clause.

Nested query issue, Invalid Identifier error

I am running following query in Oracle 10 XE and getting [Err] ORA-00904: "Q": invalid identifier
SELECT questions.sb_title Q,questions.sb_baab_id,questions.sb_fasal_id,QUESTIONS.SB_CONTENT answer,IST.SB_PREFERENCE PREF
FROM USER_QUESTIONS questions
INNER JOIN USER
ON QUESTIONS.SB_USER_ID = USER.SB_ID
INNER JOIN IST
ON IST.SB_ID = USER.SB_IST_ID
AND(Q LIKE '%where is%')
AND USER.SB_IST_ID =
(
Select issued.SB_IST_ID
FROM USER_REGISTER register_number
INNER JOIN USER_ISSUED issued
ON register_number.SB_REGISTER_NUMBER = ISSUED.SB_REGISTER_NUMBER
AND REGISTER_NUMBER.SB_REGISTER_NUMBER IN(1240)
)
You cannot reference an alias in the JOIN condition - write the actual column name: sb_title.
I don't think you can use the alias "Q" like that. You're aliasing it in your select clause, don't think you can use that alias in your ON clause. Try using the full column name (sb_title).