consider subquery of the same table in materialized view creation - oracle

Good afternoon,
how can I edit my select to avoid subquery error message inside materialized view.
ORA-22818 subquery expressions not allowed here
create materialized view vista1
refresh complete on demand
as
select f1.codigo,f1.Car,f1.codCard,f1.descripcion,f1.caracteristicas,
f1.razonsocial
f1.codigoAbs,
f1.codigoCarAbs,
(select ff.Car
from persona ff
where ff.codigo=f1.codigoabs
and ff.codCard=f1.codigoCarAbs
and rownum=1) as "absorbed reference"
from persona f1
The logic of the table and columns is as follows:
the "persona" table has columns that identify other people who were absorbed or are under guardianship,these columns are:
-codeABS y codigoCarABS
I cannot edit the structure of the tables or create others.
description:
1-the "codigo" field is the primary key of the "persona" table.
2-the "codCard" field is a unique code of the "persona" table.
3-the "codeABS" field, indicates the code of the "persona" who was absorbed, it belongs to a code from the same "persona" table.
4-the "codigoCarABS" field, indicates the CAR code of the "persona" who was absorbed, it belongs to a code from the same "persona" table.

How about a join?
SELECT f1.codigo,
f1.car,
f1.codcard,
f1.descripcion,
f1.caracteristicas,
f1.razonsocial,
f1.codigoabs,
f1.codigocarabs,
f2.car AS absorbed_reference
FROM persona f1
JOIN persona f2 ON f1.codigo = f2.codigoabs AND f1.codigocarabs = f2.codcard;
ROWNUM = 1 you used implies that there might be 2 or more rows; I believe that "my" query then misses the where clause which would make sure that only one value from f2 is fetched. Is there some timestamp column, ordinal number, ... that helps with that? If not and you don't really care which value to return, you could apply e.g. MIN function to f2.car and put the rest of selected columns into the group by clause:
SELECT f1.codigo,
f1.car,
f1.codcard,
f1.descripcion,
f1.caracteristicas,
f1.razonsocial,
f1.codigoabs,
f1.codigocarabs,
MIN(f2.car)AS absorbed_reference
FROM persona f1
JOIN persona f2 ON f1.codigo = f2.codigoabs
AND f1.codigocarabs = f2.codcard
GROUP BY f1.codigo,
f1.car,
f1.codcard,
f1.descripcion,
f1.caracteristicas,
f1.razonsocial,
f1.codigoabs,
f1.codigocarabs;

Related

Why Oracle changes rowid with fetch?

I have a query like this:
select w.rowid, w.waclogin
from tableA w, tableB wa, tableC a
where wa.alucod = a.alucod
and w.waclogin = wa.waclogin
and a.cpf = '31808013875'
and rownum <= 1;
The results are:
ROWID WACLOGIN
AAA0CEAHSAABE07ABA 31808013875
But when I use fetch (for performance) the rowid returned is different:
select w.rowid, w.waclogin
from tableA w, tableB wa, tableC a
where wa.alucod = a.alucod
and w.waclogin = wa.waclogin
and a.cpf = '31808013875'
fetch first row only;
Results in:
ROWID WACLOGIN
AAA0DMAHaAAA+ZcAAX 31808013875
Why fetch changes the rowid?
For me this no makes sense.
Update
When fetch is used, that row id returned is from table B, instead of table A.
There are two rows in tableA with the same wacLogin value (but obviously different rowID values). Neither of your queries specifies an order by so which of those rows is returned is arbitrary. Presumably, there is a slightly different query plan being used for both queries so each one returns a different arbitrary row. Of course, tomorrow, either or both queries could start returning a different arbitrary row if the query plan or physical organization of the table changes. If you want the same row to be returned in both cases, you'd need to make both queries deterministic with an order by clause that uniquely orders the results.

Query to get Unique Indexes having NOT NULL columns - Oracle

Currently I am trying to find all the unique indexes defined in a table which are NOT NULL for Oracle database. What I mean by that is, Oracle allows creating unique indexes on columns which are even defined as NULL.
So if my table has two unique indexes, I want to retrieve the particular unique index which is having all the columns having the NOT NULL constraints.
I did come up with this query:
select ind.index_name, ind_col.column_name, ind.index_type, ind.uniqueness
from sys.dba_indexes ind
inner join sys.dba_ind_columns ind_col on ind.owner = ind_col.index_owner and ind.index_name = ind_col.index_name
where ind.owner in ('ISADRM') and ind.table_name in ('TH_RHELOR') and ind.uniqueness IN ('UNIQUE')
The above query is giving me all the unique indexes with the associated columns, but I am not sure, how should I join the above query with ALL_TAB_COLS which has the NULLABILITY data for all the columns of a table.
I tried joining this table with indexes and tried subquery as well, but not getting appropriate results.
Hence, would request you to please comment on same.
Analytic functions and inline views can help.
The analytic functions let you return detailed data but also create a summary on that data, based on separate windows. The detailed results include index owner, index name, and column name, but the counts are only per index owner and index name.
The first inline view joins the three tables, returns the detailed information, and has analytic functions to generate the count of all columns and the count of all nullable columns. The second inline view only selects rows where those two counts are equal.
--Unique indexes and columns where every column is NOT NULL.
select owner, index_name, column_name
from
(
--All relevant columns and counts of columns and not null columns.
select
dba_indexes.owner,
dba_indexes.index_name,
dba_tab_columns.column_name,
dba_tab_columns.nullable,
count(*) over (partition by dba_indexes.owner, dba_indexes.index_name) total_columns,
sum(case when nullable = 'N' then 1 else 0 end)
over (partition by dba_indexes.owner, dba_indexes.index_name) total_not_null_columns
from dba_indexes
join dba_ind_columns
on dba_indexes.owner = dba_ind_columns.index_owner
and dba_indexes.index_name = dba_ind_columns.index_name
join dba_tab_columns
on dba_ind_columns.table_name = dba_tab_columns.table_name
and dba_ind_columns.column_name = dba_tab_columns.column_name
where dba_indexes.owner = user
and dba_indexes.uniqueness = 'UNIQUE'
order by 1,2,3
)
where total_columns = total_not_null_columns
order by 1,2,3;
Analytic functions and inline views are tricky but they're very powerful once you learn how to use them.

Updating rows with values from another table in ClickHouse

I have two tables, one with data about counties and another with data about states. Different states can sometimes have counties with the same exact name, so I am trying to populate a unique_name column in my counties table that is the concatenation of a county name and the abbreviation of the state where that county is located (e.g.: Honolulu County, HI).
I have come up with the following query:
ALTER TABLE counties
UPDATE unique_name =
(
SELECT concat(counties.name, ', ', states.name_abbr)
FROM counties
INNER JOIN states
ON counties.statefp = states.statefp
) WHERE unique_name = ''
However, I keep getting the following error:
DB::Exception: Unknown identifier: states.statefp, context: required_names: 'states.statefp' source_tables: table_aliases: private_aliases: column_aliases: public_columns: masked_columns: array_join_columns: source_columns: .
The inner query is working perfectly fine on its own, but I don't why this error is coming up when I try to do the update. Any ideas?
ClickHouse does not support dependent joins for ALTER TABLE UPDATE. Fortunately, there is a workaround. You have to create a special Join engine table for the update. Something like this:
CREATE TABLE states_join as states Engine = Join(ANY, LEFT, statefp);
INSERT INTO states_join SELECT * from states;
ALTER TABLE counties
UPDATE unique_name = concat(name, joinGet('states_join', 'name_abbr', statefp))
WHERE unique_name = '';
DROP TABLE states_join;
Note, it only works in 19.x versions.

How to compare the column names in one table to the values in another in impala

first is the main table and second is the lookup table.
I need to compare the column names of first table to the values in the second table and if a certain column name is found in any row of the second table then fetch some fields out of second table.
Is it possible to do it in impala?
Table 1
source |location |origin
----------+----------+-------
s1 |india |xxx
Table 2
extractedfrom|lct |lkp_value|map_value
-------------+----------+---------+---------
s1 |location |india |india_x
s1 |origin |xxx |yyyyyy
i need to have something like
final view required
source |location |origin |location_ll|origin_lkp
----------+----------+----------+-----------+----------
s1 |india |xxx |india_x |yyyyy
You should edit your post to be more specific about what you are trying to do and how you wish to join the tables.
The following query should work for you given the example you provided.
SELECT t1.source,
t1.location,
t1.origin,
t2_loc.map_value AS location_lkp,
t2_ori.map_value AS origin_lkp
FROM Table1 t1
JOIN Table2 t2_loc ON t1.source = t2_loc.extractedfrom
AND t1.location = t2_loc.lkp_value
JOIN Table2 t2_ori ON t1.source = t2_ori.extractedfrom
AND t1.origin = t2_ori.lkp_value
WHERE t2_loc.lct = 'location'
AND t2_ori.lct = 'origin'
The trick is that you join to Table2 multiple times - one for each column you wish to match upon.

Need to select column from subquery into main query

I have a query like below - table names etc. changed for keeping the actual data private
SELECT inv.*,TRUNC(sysdate)
FROM Invoice inv
WHERE (inv.carrier,inv.pro,inv.ndate) IN
(
SELECT carrier,pro,n_dt FROM Order where TRUNC(Order.cr_dt) = TRUNC(sysdate)
)
I am selecting records from Invoice based on Order. i.e. all records from Invoice which are common with order records for today, based on those 3 columns...
Now I want to select Order_Num from Order in my select query as well.. so that I can use the whole thing to insert it into totally seperate table, let's say orderedInvoices.
insert into orderedInvoices(seq_no,..same columns as Inv...,Cr_dt)
(
SELECT **Order.Order_Num**, inv.*,TRUNC(sysdate)
FROM Invoice inv
WHERE (inv.carrier,inv.pro,inv.ndate) IN
(
SELECT carrier,pro,n_dt FROM Order where TRUNC(Order.cr_dt) = TRUNC(sysdate)
)
)
?? - how to do I select that Order_Num in main query for each records of that sub query?
p.s. I understand that trunc(cr_dt) will not use index on cr_dt (if a index is there..) but I couldn't select records unless I omit the time part of it..:(
If the table ORDER1 is unique on CARRIER, PRO and N_DT you can use a JOIN instead of IN to restrict your records, it'll also enable you to select whatever data you want from either table:
select order.order_num, inv.*, trunc(sysdate)
from Invoice inv
join order ord
on inv.carrier = ord.carrier
and inv.pro = ord.pro
and inv.ndate = ord.n_dt
where trunc(order.cr_dt) = trunc(sysdate)
If it's not unique then you have to use DISTINCT to deduplicate your record set.
Though using TRUNC() on CR_DT will not use an index on that column you can use a functional index on this if you do need an index.
create index i_order_trunc_cr_dt on order (trunc(cr_dt));
1. This is a really bad name for a table as it's a keyword, consider using ORDERS instead.

Resources