Unselect the previous select - sql

I don't know it may sound weird... but here is my situation... I have to select rows from two tables (Table1) and (Table2)
Select * from Table1 Where <SomeCondition>
Select * from Table2 Where <SomeCondition>
But my constraint is If Table1 / Table2 return 0(zero) Rows... I should not return any results at all.
That ie... If 1st select returns say 10 rows and the 2nd select returns 0 (zero) rows, I should call back the first select also...
Is the Temp tables the only solution, or do we have any other alternative.
Thanks in advance for your response...
Raja

One approach is to do an IF EXISTS first:
IF EXISTS(SELECT * FROM Table1 WHERE....) AND EXISTS(SELECT * FROM Table2 WHERE....)
BEGIN
-- Now do your SELECT on each, as both return results
END
EXISTS should give good performance, as it will stop as soon as it does find a matching record.

Without more details of your specific queries, here is an option. As long as your queries aren't too complex aren't very intensive, this should work:
Select * from Table1 Where <SomeCondition>
where exists( Select null from Table2 Where <SomeCondition> );
Select null from Table2 Where <SomeCondition>
where exists ( Select null from Table1 Where <SomeCondition> );
This will only select rows in each statement if the other statement will also return any number of rows greater than zero.

An obvious but not-so-performant solution will be to count number of rows first (not sure about the syntax):
if not exists(select id from Table1 where ...) or not exists(select id from Table1 where ...)
return
Select * from Table1 Where <SomeCondition>
Select * from Table2 Where <SomeCondition>

If you can use stored procedures you can use ##rowcount to check if the second query returned any results:
create proc pTest
as
Select * from Table1 Where <SomeCondition>
Select * from Table2 Where <SomeCondition>
if ##rowcount = 0 return
go

Related

INSERT with UNION ALL returns only the first select result - HIVE Beeline

I want to do a query that inserts the result of table1 with table2 union's result. But when I try on beeline:
insert into table table3
select * from (
select * from table1 t1
where
h_time > '2019-05-01 00:00:00'
and t1.id in (select id from table4)
union all
select * from table2 t2
where
h_time > '2019-05-01 00:00:00'
and t2.id not in (select id from table4)
);
Consider that the both tables 1 and 2 have the same column numbers and datatypes have already fixed previously.
The result in table3 is only the rows of table1. And when I change the position of table 1 and 2, I get only the rows of table2.
Anyone have a guess what's happening?
Tks in advance!
it may be problem with table too, it may not show the actual count sometimes, use select * from tablename. If the count is as expected the run Analyze statement it'll re-compute and repair the statistics

What is the quickest way in Oracle SQL to find out if one or more duplicates exist in a table?

I'm looking to create a statement that stops and returns true the very second it finds a duplicate value on a column. I don't care what the value is and simply need to know whether a duplicate exists or not; nothing else.
I know i can write Select count(*) from myTable group by primary_id having count(*) > 1; but this goes through every single row of the table, whereas I want the query to stop as soon as it encounters a single case of a duplicate existing.
The best shot i've attempted with what i know is this:-
select 1 as thingy from dual outer_qry
where exists
(
select * from
(
select some_ID,
case when COUNT(*) > 1 then 'X' else 'N' end as TRIG
from myTable
group by some_ID
)INNER_QRY
where INNER_QRY.trig = outer_qry.dummy
);
However this takes 13 seconds and I doubt it takes that long to find the first duplicate.
Can anyone please suggest where my thinking is going wrong as, hopefully from my SQL, my assumption is that the EXISTS function will be checked for every row returned for the inner_qry, but this doesn't seem to be the case.
You would use exists. This returns all the duplicates:
select t.*
from mytable t
where exists (select 1
from mytable t t2
where t2.some_id = t.some_id and t2.rowid <> t.rowid
);
In Oracle 12c, you would add fetch first 1 row only. And it can take advantage of an index on mytable(some_id).
In earlier versions:
select 1 as HasDuplicate
from (select t.*
from mytable t
where exists (select 1
from mytable t t2
where t2.some_id = t.some_id and t2.rowid <> t.rowid
)
) t
where rownum = 1;
If this returns no rows, then there are no duplicates.
select * from table1 t1 natural join table1 t2 where t1.rowid < t2.rowid;
you can use this to understand which id is dublicate
select some_ID
from myTable
group by some_ID having count(*) >1

Choose which query will be used / Conditional query in Oracle

I have two queries, query1 and query2. What I would like to do is, if returned rows of query1 is empty, return query2 instead. Is that possible using basic SQL query alone? They have same returning columns btw, but different table sources.
eg:
query1:
SELECT name, message
FROM table1
query2:
SELECT name, message
FROM table 2
If query1 is empty, return name, message from query2.
This will select from table1 if not empty, otherwise select from table2:
SELECT * FROM table1
WHERE EXISTS (select * from table1)
UNION ALL
SELECT * FROM table2
WHERE NOT EXISTS (select * from table1)
This checks if table1 has no rows:
EXISTS (SELECT * FROM TABLE)
Found an answer here: https://stackoverflow.com/a/25122516/3747493
Basically:
SELECT *
FROM table1
UNION ALL
SELECT *
FROM table2
WHERE (SELECT COUNT(*) FROM table1) = 0
Thanks guys!

Select All Values From Table That Match All Values of Subquery

So I have a list of values that is returned from a subquery and would like to select all values from another table that match the values of that subquery. Is there a particular way that's best to go about this?
So far I've tried:
select * from table where tableid = select * from table1 where tableid like '%this%'
select * from table where tableid in(select tableid
from table1
where tableid like '%this%')
select * from table where tableid IN
(select tableid from table1 where tableid like '%this%')
A sub-query needs to return what you are asking for. Additionally, if there's more than 1 result, you need IN rather than =
This will work
select * from table where tableid in
(select tableid from table1 where tableid like '%this%')
= works when subquery returns 1 record only
in works when subquery returns 1 or more than one record only
I am reading a SQL Server book right now, and it highlights doing this using the EXISTS statement in the WHERE clause for speed and efficiency purposes. Here's a potential solution.
SELECT
*
FROM
tableName AS t
WHERE
EXISTS(
SELECT
1
FROM
table1 AS s --as in subtable or something like that
WHERE
t.tableid = s.tableid
AND
s.tableid like '%this%'
)

Two SQL statements, ignore the return of the first if it has no results?

I have a sql statement SELECT * FROM table1 WHERE ....; SELECT * FROM table2 WHERE ....
What I want is to get the results from the first select statement if it returns results, but if it doesn't, I want to ignore it and just get the results from the second select statement. Is there a way I can do this just using SQL?
I'm getting this returned to me as a datatable, using a dataadapter to fill the datatable from the above SQL statement. I can't change that part, or switch to filling a dataset (for reasons I won't get into, but it just can't be changed).
Assuming both queries return the same number and type of columns, one way to do this would be:
select * from table1 where ... /* query 1 conditions */
union all
select * from table2 where ... /* query 2 conditions */
and not exists
(select 1 from table1 where ... /* query 1 conditions */)
A couple options. You can check the count first:
If (select count(*) from table1 where...) > 0
begin
select * from table1 where...
end
else
begin
select * from table2 where...
end;
if both result sets are identical in structure, you can save the count check (and thus improve performance) by using a temp table:
create table #temp (col1 int, col2 varchar(10), ...);
insert #temp
select * from table1 where...;
if ##rowcount = 0
begin
insert #temp
select * from table2 where...
end;
select * from #temp;