query with LEAST returning multiple rows in oracle - sql

When I ran the below query in Oracle 11g
SELECT least(val)
FROM
(
SELECT 1 AS val
FROM dual
UNION
SELECT 2 AS val
FROM dual
UNION
SELECT 3 AS val
FROM dual
);
I was expecting a single row but it is returning multiple rows. please help me out where exactly my understanding is going wrong..

Oracle's LEAST function returns the least value in a list of expressions, e.g. LEAST(1, 2, 3) would return 1. So LEAST could be used to find the minimum value across a collection of columns, e.g. LEAST(col1, col2, col3). What you are seeing is to be expected, i.e. you are getting back three records with the smallest value of each record.
Instead, if you want the minimum over an aggregate of rows, then you should be using MIN, e.g.
select min(val)
from
(
select 1 as val from dual union all
select 2 from dual union all
select 3 from dual
);

Related

Trying to create Row number for Distinct values in BigQuery

On BigQuery, I'm trying to get the row count of the distinct values to display for easy reference.
Assuming I have 1000 distinct values and I'm trying to get the 340th row of distinct value, how should i code it.
I tried to run
SELECT
DISTINCT column_2
FROM
table
and sure it turns out all the DISTINCT values of column_2. But how do i add the row number beside, and would I be able to put a WHERE for the row number?
Consider below approach
select distinct column_2
from your_table
qualify 340 = dense_rank() over(order by column_2)
Since BigQuery works parallelized there is no guarantee/need for any sorting of table rows. That also means there are no row numbers.
If you want the nth element of a query result you need to define a sorting logic beforehand. You can use navigational functions for that, or a LIMIT with OFFSET if you need one exact value
with t as (
select 'a' as val
union all select 'a'
union all select 'b'
union all select 'c'
union all select 'c'
union all select 'f'
union all select 'y'
union all select 'z'
union all select 'a'
)
select
distinct val
from t
order by 1
-- 5th element has offset 4
limit 1 offset 4

How can I add two columns sequentially (and not concatenate)?

I am trying to pull two tables from an Oracle SQL database, and want to join them sequentially, so they appear as if they are one list.
List one has items [1,2,3,4]
List two has items [a,b,c,d]
I want to output [1,2,3,4,a,b,c,d]
Any thoughts?
One option uses a UNION with a computed column:
SELECT val
FROM
(
SELECT val, 1 AS position FROM table1
UNION ALL
SELECT val, 2 AS position FROM table2
) t
ORDER BY
position, val;
Demo
Note that I assume that all data here is text. If not, e.g. the first table be numeric, then we would have to do a cast along the way. But, this is not the main focus of your question anyway.
SELECT id_1, value_column1 from table_1
UNION
SELECT id_2, value_column2 from table_2;
if the types of columns are different - make sure you cast/convert them to char() - the resulting type should be same.
https://docs.oracle.com/cd/B19306_01/server.102/b14200/queries004.htm
use union, i think 1,2,3 as numeric value that why converted it on varchar as for union you have to same data type
with t1 as (
select 1 as id from dual union all
select 2 from dual union all
select 3 from dual union all
select 4 from dual
), t2 as (
select 'a' as item from dual union all
select 'b' from dual union all
select 'c' from dual union all
select 'd' from dual
)
select cast(id as varchar(20)) as id from t1
union
select * from t2
demo
output
1
2
3
4
a
b
c
d

Union and union all in oracle Database

While executing the below two queries (focus on the part between two asterisks * ____ *), I am really wondering how does the position of UNION ALL changes the output. I am unable to understand.
Query 1
SELECT 'Jack' AS Name, 100 AS Marks FROM DUAL
*UNION All SELECT 'Jack' AS Name, 100 AS Marks FROM DUAL*
UNION SELECT 'Jack' AS Name, 100 AS Marks FROM DUAL
Query Result
NAME MARKS
Jack 100
Query 2
SELECT 'Jack' AS Name, 100 AS Marks FROM DUAL
UNION SELECT 'Jack' AS Name, 100 AS Marks FROM DUAL
*UNION ALL SELECT 'Jack' AS Name, 100 AS Marks FROM DUAL*
Query Result
NAME MARKS
Jack 100
Jack 100
Thanks :)
If you don't specify parantheses, the selects would get executed one after the other. All set operators minus, union, union all, intersect have the same precedence.
Oracle Documentation
In the first query, UNION is performed at the end so there would be no dup rows per the query. In the second, UNION ALL is performed at the end, so there would be dup rows per your query.
The difference between Union and Union all is that Union all will not eliminate duplicate rows,
first query output:
step 1:
SELECT 'Jack' AS Name, 100 AS Marks FROM DUAL
UNION All SELECT 'Jack' AS Name, 100 AS Marks FROM DUAL
result 2 rows because union all allows duplicates.
step 2:
UNION SELECT 'Jack' AS Name, 100 AS Marks FROM DUAL
this query will pick only row without duplicates from the above 2 rows and itself.
returns 1 row.
in the second query...
step 1
SELECT 'Jack' AS Name, 100 AS Marks FROM DUAL
UNION SELECT 'Jack' AS Name, 100 AS Marks FROM DUAL
returns 1 row because union selects only distinct rows.
step 2
UNION ALL SELECT 'Jack' AS Name, 100 AS Marks FROM DUAL
return 2 rows because it allows duplicates.
Both union and union all have the same precedence as operations. So in the absence of parentheses, your two unions would be evaluated from top to bottom. Your first query is being evaluated like this:
SELECT Name, Marks
FROM
(
SELECT 'Jack' AS Name, 100 AS Marks FROM DUAL
UNION All
SELECT 'Jack' AS Name, 100 AS Marks FROM DUAL
) t
UNION
SELECT 'Jack' AS Name, 100 AS Marks FROM DUAL
The same reasoning applies to your second query.
To understand this behavior,you need to be clear with the difference between UNION and UNION ALL.
Query 1: Output of first two lines will return 2 rows. However, last line(sql statement) with 'UNION' operator will remove duplicate rows,including it's own output. So, total first query will return only 1 row.
Query 2: Now, UNION is on 2nd line. After getting combined with 1st line, it will again return only 1 row. But, on the 3rd line with 'UNION ALL',it will return 2 rows. Because, 'UNION ALL' won't remove duplicates.

input string to table

I am doing some debugging in SQL for oracle 10g. I have a big input string which is used in "IN Clause" i.e.
select * from table where col in ('str2','str3','str4','str5',...)
i want to convert the in clause to rows or table?
Is there a way to do this i.e.
select 'str2','str3','str4','str5', .. from dual
but this outputs multiple columns and i want multiple rows?
Edit:
Here is what i am trying to do. suppose i have an excel data in tmp_table1 (cant create in reality) and tmp_table1 is same as the IN clause, then the below statement will give the missing keys.
SELECT *
FROM tmp_table1
WHERE unique_id NOT IN (
SELECT unique_id
FROM table1
WHERE unique_id IN
('str1', 'str2', 'str3', 'str4'))
now #andriy-m solution works if the in string is less than 4000. but what if its greater?
You are probably looking for this solution.
You can UNION the values into multiple rows:
SELECT 'str2' AS col FROM dual
UNION
SELECT 'str3' FROM dual
UNION
SELECT 'str4' FROM dual
UNION
SELECT 'str5' FROM dual

Union returns two rows if data is different, one if it's the same! Why?

Taking the following statement:
select count( 1 ) as cnt from tbl where val= 1
union
select count( 1 ) as cnt from tbl where val = 0
If the two selects return the same value the result is a single row with that value. If the selects return different values the result is two rows with the two values. Why?
I am trying to find the total count of rows using:
select sum (cnt) from
(
select count( 1 ) as cnt from tbl where value = 1
union
select count( 1 ) as cnt from tbl where value = 0
) as tbl2
which works as expected if the counts are different but gives half the value if the counts are the same...
(PS : More interested in why sql behaves this way than in a solution)
This behavior is by design. You should use UNION ALL to achieve the behavior you want. Basically, UNION performs a set union operation, removing the duplicates in the set.
http://www.fmsinc.com/free/NewTips/SQL/SQLtip5.asp
the main difference between union and union all is that union does a distinct over all fields returned. Where union all just returns and joins the various result sets