Using a variable from Oracle AS clause - oracle

I'm using the following as part of a query
SELECT
MEMO_COMMENT as MEMO,
INSTR(MEMO, 'PD') AS PastDue
FROM table
The error I receive is "MEMO": invalid identifier
I also tried
` WITH MEMO AS (select MEMO_COMMENT FROM table)
select INSTR(MEMO, 'PD') AS PastDue`
FROM table
and received the same error
Is there a way to declare the field like this? I feel like I'm missing something obvious.

In the first one, you can't use the alias as a select field at the same nesting level, so it is the second reference that is wrong:
SELECT
MEMO_COMMENT as MEMO,
INSTR(MEMO, 'PD') AS PastDue
FROM table
Should be:
SELECT
MEMO_COMMENT as MEMO,
INSTR(MEMO_COMMENT , 'PD') AS PastDue
FROM table
Or you can reference the alias from a higher nesting level, for example:
SELECT
INSTR(MEMO , 'PD') AS PastDue
FROM ( SELECT
MEMO_COMMENT as MEMO
FROM table )
For the second, the WITH statement, you are aliasing the dataset as a table named MEMO - not the field. This would work though:
WITH MEM_DATA AS (select MEMO_COMMENT as MEMO FROM table)
select INSTR(MEMO, 'PD') AS PastDue`
FROM MEM_DATA;

Related

ORACLE - If in SELECT Statement

I have a select and I need to hide data in a column when some other column meets criteria. Is there a way to do that in Select statement ?
Here is what I tried:
SELECT acc.account_no, (case substr(acc.bank,18,3) when acc.account_no like'%011006000%' then ' ' end) "BANK_ACCOUNT", sum(acc.bills) "BILLS"
FROM BNK.Bank_Transaction acc
WHERE acc.Bill_Date BETWEEN '01.05.2018' AND '29.05.2018'
AND (acc.account_no LIKE '%011006000%'
OR acc.account_no LIKE '%011076000%')
I receive ORA-00905: missing keyword error in upper select.
You may need:
select case when account_no like '%011006000%'
then null
else substr(..)
end as yourColumn,
...
from ...

can I use `=` sign operator with sub-query instead of `IN`

I am just wondering if use = sign operator with sub-query instead of IN
Is it correct way ? and meet the oracle standard ?
Example
select column_name from my_table_1 where id = (select max(id) from my_table_2);
The Difference is related to the number of rows returned. If you have only one row returned from nested sql you may prefer both = or in operators. But if multiple rows returned from nested query, use in operator.
So, in your sql example you may prefer using any of the operators. Since, max functions returns only one row.
As you are fetching maximum value from subquery to compare with id, Both(= and IN )will work fine. But If you are trying to fetch more than one row then you have to use IN keyword.
If you have 1 result in sub query you are fine with using = sign, except when data type is wrong, for example , checking with same data type of dummy VARCHAR2(1)
select * from dual where 'X' = (select max(dual.dummy) from dual);
Is similar to using in (also same explain plain)
select * from dual where 'X' in (select max(dual.dummy) from dual);
But checking with different/wrong data type will result with exception ORA-01722 Invalid number
select * from dual where 1 =(select max(dual.dummy) from dual);

Hive LATERAL VIEW and WHERE Clause using Sub query

I'm looking for a way to optimize my query.
We have a table with events called lea, with a column app_properties, which are tags, stored as a comma separated string.
I would like to select all the events that match the result of a query that select the desired tags.
My first try:
SELECT uuid, app_properties, tag
FROM events
LATERAL VIEW explode(split(app_properties, '(, |,)')) tag_table AS tag
WHERE tag IN (SELECT source_value FROM mapping WHERE indicator = 'Bandwidth Usage')
But Hive will not allow this...
FAILED: SemanticException [Error 10249]: Line 4:6 Unsupported SubQuery Expression 'tag': Correlating expression cannot contain unqualified column references.
Gave it another try by replacing WHERE tag IN by WHERE tag_table.tag IN but not luck...
FAILED: SemanticException Line 4:6 Invalid table alias tag_table' in definition of SubQuery sq_1 [tag_table.tag IN (SELECT source_value FROM mapping WHERE indicator = 'Bandwidth Usage')] used as sq_1 at Line 4:20.
In the end... The query below gives the desired result, but I've a feeling that this is not the most optimized way of solving this use case. Has anyone ran into the same use case where you need the select from a LATERAL VIEW using a Sub query?
SELECT to_date(substring(events.time, 0, 10)) as date, t2.code, t2.indicator, count(1) as total
FROM events
LEFT JOIN (
SELECT distinct t.uuid, im.code, im.indicator
FROM mapping im
RIGHT JOIN (
SELECT tag, uuid
FROM events
LATERAL VIEW explode(split(app_properties, '(, |,)')) tag_table AS tag
) t
ON im.source_value = t.tag AND im.indicator = 'Bandwidth Usage'
WHERE im.source_value IS NOT NULL
) t2 ON (events.uuid = t2.uuid)
WHERE t2.code IS NOT NULL
GROUP BY to_date(substring(events.time, 0, 10)), t2.code, t2.indicator;
The Hive subquery in the WHERE clause can be used with IN, NOT IN, EXIST, or NOT
EXIST as follows. If the alias (see the following example for the employee table) is not specified before columns (name) in the WHERE condition, Hive will report the error Correlating expression cannot contain unqualified column references. This is a limitation of the Hive subquery.
From Apache Hive Essentials.
I guess this problem is also caused by subquery.
events should have an alias

Oracle Insert, Update, Delete Trigger with Join

I'm trying to implement Oracle triggers for child views but I need to be able to join the child views to their parents in order to do a role permission check.
In SQL Server I'm able to stuff like this:
ALTER TRIGGER [dbo].[ASetTrt_I] ON [dbo].[UCV_ASet_TRT]
INSTEAD OF Insert AS
BEGIN
SET NOCOUNT ON;
IF EXISTS (SELECT 1 from INSERTED i INNER JOIN [Analysis_Sets] p on i.[key] = p.[ID]
WHERE ([dbo].IsMemberOf(p.[UpdateRole]) <> 1 and [dbo].IsMemberOf('db_owner') <> 1))
RAISERROR ('Update failed due to insufficient permission',11,1)
INSERT INTO [Set_Trts] ( [ID], [Name], [key], [f_lTreatmentKey], [f_lOrder] )
SELECT
inserted.[ID], inserted.[Name], inserted.[key], inserted.[f_lTreatmentKey], inserted.[f_lOrder]
FROM inserted
INNER JOIN [Sets] parentT
on inserted.[key] = parentT.[ID]
WHERE (([dbo].IsMemberOf('db_owner')=1) or ([dbo].IsMemberOf(parentT.[UpdateRole])=1))
END
Is there anything I can do in Oracle to replicate the join functionality?
I've tried selecting from :New the way that SS selects from inserted but that doesn't seem to work..
Thanks.
You don't need to join. The:new pseudorow is just available and can be referenced like a record type. It isn't a table-like structure, and is only available in a for each row trigger. So your insert would be something like:
INSERT INTO Analysis_Set_Trts ( ID, Name, f_lAnalysisSetKey, f_lTreatmentKey,
f_lOrder )
SELECT :new.ID, :new.Name, :new.f_lAnalysisSetKey, :new.f_lTreatmentKey,
:new.f_lOrder
FROM Analysis_Sets parentT
WHERE parentT.ID = :new.f_lAnalysisSetKey
AND ((IsMemberOf('db_owner')=1) or (IsMemberOf(parentT.UpdateRole)=1));
... although not quite sure what the last line is doing or what the equivalent is.

Order of columns returned in SQL query (With table join)

I am wondering what determines the order of columns returned in a SQL query.
For example, SELECT * FROM SOMETABLE;
SQ_ID |BUS_TYPE |VOIP |LOCAL_PHONE
--------|-----------|---------|-------------
SQ000001|Business |Y |N
I am guessing the attribute COLUMN_ID determines this. In the case of a table join, for example, SELECT * FROM SOMETABLE LEFT JOIN OTHERTABLE USING (SOME_COL); how is the order now determine.
The order of columns in SELECT * FROM some_table is determined by the column_id of each column, as seen in USER_TAB_COLUMNS.
The order of columns in SELECT * FROM some_table JOIN other_table is all the columns for each table starting with the leftmost table after the FROM clause. In other words, this ...
SELECT * FROM some_table JOIN other_table
... is equivalent to this ...
SELECT some_table.*, other_table.* FROM some_table JOIN other_table
Changing that inner join to LEFT JOIN or RIGHT JOIN won't change the projection.
This is, of course, theoretical. We should never use select * in production code. Explicit column declarations, with table aliases when joining, are always safer. Apart from better expression of intent, explicit projections protect our code from future changes to the tables such as adding a LOB column or a column name which creates ambiguity with a joined table's column.
You can list the order of the colums in the Select statement:
SELECT SOME_COL, SOME_OTHER_COL
FROM SOMETABLE LEFT JOIN OTHERTABLE USING (SOME_COL)
But you also speak of the ID influencing the order and of ordering in general. So I think you could also be looking for ORDER BY to order the rows:
SELECT *
FROM SOMETABLE LEFT JOIN OTHERTABLE USING (SOME_COL)
ORDER BY SOME_COL
What also comes quite handy in this case is the use of aliases. Especally when both tables have coloums with the same name:
SELECT s.some_col, o.some_col
FROM SOMETABLE s LEFT JOIN OTHERTABLE o ON(o.id = s.id)
ORDER BY o.SOME_COL
I use the ON JOIN syntax in this case, because i find this more intuive when using aliases but it should also work with USING.

Resources