Oracle union clarification needed for query with union join - sql

below is just an example which resembles to union query which i am running. i have a question around alias table xyz_1. How oracle takes care of such alias table created along with union? does oracle run both statements in different SGA and hence they are not visible to each other?
select * from
abc, (select a from xyx where c='yes') xyz_1
where
abc.col_1 = xyz_1.col_1
union
select * from
abc, (select a from xyx where c='no') xyz_1
where
abc.col_1 = xyz_1.col_1

UNION is a set operator whose function is to combine the results of two queries. Both queries are executed independently, else it is ok to use the same table alias in both queries, as you would usually do in a subquery for example. The only constraint when using UNION is that the two queries must return the same number of fields, and with similar datatypes (considering that implicit conversion may happen).
The the Oracle docs do not mention any restriction on aliasing within subqueries :
You can combine multiple queries using the set operators UNION, UNION ALL, INTERSECT, and MINUS. All set operators have equal precedence. If a SQL statement contains multiple set operators, then Oracle Database evaluates them from the left to right unless parentheses explicitly specify another order.

Related

Oracle SQL: single SELECT request for multiple owners

I would like your advice on the best method to use.
From a single Oracle server, we have 3 different owners that contain the exact same tables/data structures. Essentially, the owners allow us to separate the data by administrative regions.
Currently, when I want to do a SQL query on the entire data set (regions), I have to do 3 separate queries:
select * from owner1.Table1 union all
select * from owner2.Table1 union all
select * from owner3.Table1
In this simple example, there are no issues, but if the query is complex, it quickly becomes very difficult to maintain.
So, would there be a more efficient way to make only one global query instead of 3. I guess it's possible to do it via a PL/SQL script, or Dynamic SQL, but I don't know...
Basically, I would like to be able to do (where owners would contain the names of my 3 owners):
select * from owners.Table1
It is not possible to build views that would contain the data of all 3 owners (there would be too many).
Thanks
In this simple example, there are no issues, but if the query is complex, it quickly becomes very difficult to maintain.
So, would there be a more efficient way to make only one global query instead of 3.
Use a sub-query factoring clause (a.k.a. a CTE) to combine the queries with the simple UNION ALL queries and then perform the complex query on the combined table (rather than trying to perform the queries on the individual tables):
WITH subquery_name AS (
select * from owner1.Table1 union all
select * from owner2.Table1 union all
select * from owner3.Table1
)
SELECT <your complex query>
FROM subquery_name;

SQL Server performance on concat method

I need to write a query to fetch some data from table and need to use concat method. I end up preparing two different queries and I'm not sure which one will have better performance when we have huge amounts of data.
Please help me understand which query will perform better, and why.
I need to concat twice, one for displaying and one for where condition:
select
id, concat(boolean_value, long_value, string_value, double_value) as Value
from
table
where
concat(boolean_value, long_value, string_value, double_value) = 'XX'
Write the above query as a subquery and add the where condition
Select *
from
(select
id, concat(boolean_value, long_value, string_value, double_value) as Value
from
table) as output
where
Value = 'XX'
Note: this is sample query and the actual query will have multiple joins and the need to concat from multiple columns of different tables
SQL databases represent the result set being produced. You seem to be asking if there is common expression elimination -- that is, will the concat() be performed exactly once.
You have a better chance of this with the subquery than with the version that repeat the expression. But SQL Server could be smart enough to only evaluate it once.
If you want to guarantee single evaluation, then I think cross apply does that:
select t.id, v.value
from table t cross apply
(values (concat( boolean_value, long_value, string_value, double_value))
) as Value
where v.value = 'XX';
I would, however, question why you are comparing the result of the concat() rather than the base columns. Comparing the base columns would allow the optimizer to take advantage of indexes, partitions, and statistics.
You may run EXPLAIN on both queries to see what exactly is on the mind of SQL Server. I would expect that the first version would be preferable, because, unlike the second version, it does not force SQL Server to materialize an intermediate table. Regarding whether or not SQL Server would have to actually evaluate CONCAT twice in the first version, it may not even matter if the cost of the subquery be very high.

what is the corresponding query in Oracle db

I have the following query which works perfectly in postgresql:
Select 'Tom' as name
output as:
name
Tom
What should be the corresponding query in Oracle?
If I run the query in Oracle it gives an error, but is run successfully in postgresql.
Oracle doesn't allow queries without a from clause. For these kind of queries, Oracle provides a system table called dual, with one column and one row:
SELECT 'Tom' as name FROM dual
Oracle needs the from clause. In that case, you have to use the DUAL table.
select 'Tom' as name from dual;
Oracle is (afaik) unusual amongst other RMDBSs in that it enforces that if you're selecting something, you must select it from a table.
To that end, there is the DUAL table. It is a special, one row, one column table that allows you to select constants, functions etc within SQL, rather than having to write a PL/SQL procedure.
I say "special" because, since 10g, the optimizer recognises that it's different to other tables and can therefore make use of that information when generating the execution path to make it more efficient than if it was using a "normal" one column, one row table.

UNION Statement Showing Inconsistent Results

I have a SQL query that consists of two SELECT statements which are UNION'ed together. When run individually they the first SELECT returns 10 records and the second SELECT returns 1 record, so when I UNION the two SELECTs I would expect to get 11 records returned but this is not the case, I'm only getting 9 records.
Due to the nature of the SQL I can't actually post it here but it consists of numerous JOINS across 5 tables. Everything being returned is correct and valid.
Just wondering if anyone has seen this issue occur when UNION'ing two SELECT statements and if anyone has any advice on what could be the cause or even point me in the right direction, thanks.
UNION remove duplicates by default. To prevent duplicates from being removed UNION ALL should be used.
Quoting the documentation:
The default behavior for UNION is that duplicate rows are removed from the result. The optional DISTINCT keyword has no effect other than the default because it also specifies duplicate-row removal. With the optional ALL keyword, duplicate-row removal does not occur and the result includes all matching rows from all the SELECT statements.
By default, Oracle applies an implicit distinct clause to the result of a union. You may want to check whether the results of your separate queries include common items.
If you do not want this behavior, you need to use the UNION ALL clause instead.
try to use UNION ALL instead of only UNION. UNION only returns distinct rows. Check this out.

SQL "WITH" Clause/Statement

Before I begin by putting a lot SQL statements to help solve my issue I might be able to get the answer by asking a simple question. I use SQL Server 2005 on a daily basis and use the "WITH" clause to perform sub-queries. I am unfortunately in a situation now where I have to use SQL Compact which does not allow the use of the "WITH" clause to perform sub queries. What is the substitute of the "WITH" clause in SQL Compact. On average I am using 10 sub queries at a time.
As long as none of your CTE's (Common Table Expression - the formal name for the feature you are using) are recursive, remember that in the simplest form,
;WITH Q1 As
(
SELECT columns FROM Table1
)
SELECT columns FROM Q1
Can be roughly translated to:
SELECT columns FROM (SELECT columns FROM Table1) Q1
Note the 'Q1' on the end there. You have to give the subquery a name. The name you choose often doesn't matter, and so simple names are common here -- even just single letters. With 10 subqueries to string together, you might need to choose something more meaningful.
Create a temp table with the result of each with clause; use the temp tables instead of the with clause.