fetch different columns from two tables and combine the results - oracle

I want to combine the Two different tables result in oracle.
conditions:
From both the tables ID ,STAMp columns are common columns.
Remaining columns are different.
Table1;
Element_ID STAMP Col1 Col2
1 22/03/2014 85 100
2 22/03/2014 95 105
Table2.
Element_ID STAMP Col3 Col4
5 22/03/2014 100 110
6 22/04/2014 200 210
Result:
Element_ID STAMP Col1 Col3
1 22/03/2014 85 null
5 22/03/2014 null 100
Query:
Select Element_ID, Stamp, Col1 from Table1 where element_ID in (1, 5)
Select Element_ID, STAMP, Col3 from Table2 where Element_ID in (1,5)
How to combine the above two queries results, and results should come as above format.

You can try as this,
Select Element_ID, Stamp, Col1, NULL Col3 from Table1 where element_ID in (1,5)
union
Select Element_ID, STAMP, NULL Col1, Col3 from Table2 where Element_ID in (1,5)

Select T1.Element_ID,T1.Stamp, T1.Col1, T2.Col3
from Table1 T1, Table2 T2
where T1.Element_ID in (1, 5)

This is one interesting use case for a RIGHT JOIN on some minimum set -- both to restrict the result to records 1 and 5 and to force the presence of those two records:
SELECT "Element_ID", "STAMP", "Col1", "Col3"
FROM Table1
FULL OUTER JOIN Table2
USING("Element_ID", "STAMP")
RIGHT JOIN
(
SELECT 1 "Element_ID" FROM DUAL
UNION ALL SELECT 5 FROM DUAL
) MinimumSet
USING("Element_ID")
See http://sqlfiddle.com/#!4/725d9/18 for a live example

Related

Fetch name based on comma-separated ids

I have two tables, customers and products.
products:
productid name
1 pro1
2 pro2
3 pro3
customers:
id name productid
1 cust1 1,2
2 cust2 1,3
3 cust3
i want following result in select statement,
id name productid
1 cust1 pro1,pro2
2 cust2 pro1,pro3
3 cust3
i have 300+ records in both tables, i am beginner to back end coding, any help?
Definitely a poor database design but the bad thing is that you have to live with that. Here is a solution which I created using recursive query. I don't see the use of product table though since your requirement has nothing to do with product table.
with
--Expanding each row seperated by comma
tab(col1,col2,col3) as (
Select distinct c.id,c.prdname,regexp_substr(c.productid,'[^,]',1,level)
from customers c
connect by regexp_substr(c.productid,'[^,]',1,level) is not null
order by 1),
--Appending `Pro` to each value
tab_final as ( Select col1,col2, case when col3 is not null
then 'pro'||col3
else col3
end col3
from tab )
--Displaying result as expected
SELECT
col1,
col2,
LISTAGG(col3,',') WITHIN GROUP( ORDER BY col1,col2 ) col3
FROM
tab_final
GROUP BY
col1,
col2
Demo:
--Preparing dataset
With
customers(id,prdname,productid) as ( Select 1, 'cust1', '1,2' from dual
UNION ALL
Select 2, 'cust2','1,3' from dual
UNION ALL
Select 3, 'cust3','' from dual),
--Expanding each row seperated by comma
tab(col1,col2,col3) as (
Select distinct c.id,c.prdname,regexp_substr(c.productid,'[^,]',1,level)
from customers c
connect by regexp_substr(c.productid,'[^,]',1,level) is not null
order by 1),
--Appending `Pro` to each value
tab_final as ( Select col1,col2, case when col3 is not null
then 'pro'||col3
else col3
end col3
from tab )
--Displaying result as expected
SELECT
col1,
col2,
LISTAGG(col3,',') WITHIN GROUP( ORDER BY col1,col2 ) col3
FROM
tab_final
GROUP BY
col1,
col2
PS: While using don't forget to put your actual table columns as in my example it may vary.

row number based on unique column value in oralce?

I do need to implement a oracle sql to have row number defined as below:
row_num, column1, column2, cloumn3
1, ABC, 123, a1
1, ABC, 125, a2
2, ABD, 123, a3
2, ABD, 124, a4
2, ABD, 125, a5
3, ABE, 123, a1
Here I defined row number based on unique value of column1.
Can any one help me to write oracle sql to define row number in this way?
Thanks
Venkat
You need the DENSE_RANK() analytic function:
WITH your_table AS (SELECT 'ABC' col1, 123 col2, 'a1' col3 FROM dual UNION ALL
SELECT 'ABC' col1, 125 col2, 'a2' col3 FROM dual UNION ALL
SELECT 'ABD' col1, 123 col2, 'a3' col3 FROM dual UNION ALL
SELECT 'ABD' col1, 124 col2, 'a4' col3 FROM dual UNION ALL
SELECT 'ABD' col1, 125 col2, 'a5' col3 FROM dual UNION ALL
SELECT 'ABE' col1, 123 col2, 'a1' col3 FROM dual)
-- end of subquery mimicking your_table with data in; See SQL below:
SELECT dense_rank() OVER (ORDER BY col1) row_num,
col1,
col2,
col3
FROM your_table
ORDER BY col1, col2, col3;
ROW_NUM COL1 COL2 COL3
---------- ---- ---------- ----
1 ABC 123 a1
1 ABC 125 a2
2 ABD 123 a3
2 ABD 124 a4
2 ABD 125 a5
3 ABE 123 a1
DENSE_RANK() is similar to RANK() in that it will assign tied rows the same rank (that is, rows that have the same values in the columns being ordered - in your case, col1), but unlike RANK(), DENSE_RANK() won't skip rank numbers.
You can use this as well, but I forgot about dense rank. So Boneist's answer is better.
select rn.row_num , t.* from
(select column1,row_number() over (order by column1) as row_num from
(select distinct column1 column1 from tbl23) )rn
inner join tbl23 t
on rn.column1=t.column1

return null if no rows found oracle query with IN clause

I have a table with three columns.
I query that table with IN clause.
select column1 from table1 where column1 in (1,2,3) order by column2, column3
The table1 contains only values 1 and 2 in column1. I want to return the not available value also in my result, and that should be sorted in the bottom.
example data
column1 column 2 column 3
1 100 11
2 101 50
output, the not available values should be in the last.
column1 column 2 column 3
1 100 11
2 101 50
3 null null
I tried with subquery with NVL, like select nvl((select.. in(1,2,3)),null) from dual, due to IN Clause, I am getting single row subquery returns more than one row issue, which is expected.
Also tried with the union but nothing works. Great if any help. Thanks
I think you can do it with a union all:
select column1 from table1 where column1 in (1,2,3) order by column2, column3
union all
select null from table1 where column1 not in (1,2,3) order by column2, column3
If you can't take 1,2,3 values from another table you can try with:
with t1 as (
select col1,col2,col3
from tab1
where cod_flusso in ('1','2','3')),
t2 as (
select '1' as col1,null,null
from dual
union
select '2',null,null
from dual
union
select '3',null,null
from dual)
select t2.col1,col2,col3
from t2
left outer join t1
on t1.col1= t2.col1
It's better if you can store 1,2,3 values in a second table, then use left outer join.

Generate difference between 2 tables listing columns from both tables

Have 2 tables with same columns and want to generate the difference between the tables and want to show the difference listing all columns from both tables
example:
select a.*,b.* from (
(
select a.col1,a.col2 from
(select col1, col2 from table1 minus select col1, col2 from table2) as a
)
union
(
select b.col1, b.col2 from
(select col1, col2 from table2 minus select col1, col2 from table2) as b
)
)
The result should be
a.col1 a.col2 b.col1 b.col2
a.FName a.ZipCode b.FName b.ZipCode
John <same value> Jane <same value as A>
Alpha 1234 Beta 2345
My query returns exception that it is missing R parenthesis after the 1st minus keyword
I think you are trying to find rows from table a which are missing in table b and rows in table b which are missing from table a. However, there is no point in joining these two sets. Try the following query and see if it works for you.
SELECT col1, col2, 'Missing from table 2' title
FROM
(
SELECT col1,
col2
FROM table1
MINUS
SELECT col1,
col2
FROM table2
)
UNION ALL
SELECT col1, col2, 'Missing from table 1' title
FROM
(
SELECT col1,
col2
FROM table2
MINUS
SELECT col1,
col2
FROM table1
)

sort only particular rows sql server

I have six rows like
col1 col2
--------------
Apple 120
XApple 140
Banana 130
Xbanana 150
Car 110
XCar 160
I would like to sort these rows on col2 but leave the rows with 'X' alone.
so after sorting the rows should be like
col1 col2
--------------
Car 110
Apple 120
Banana 130
XCar 160
XApple 140
Xbanana 150
meaning, the rows with car apple and banana should be sorted but the rows with xcar, xapple and xbanana should be left alone and just be appended at the end.
I tried
select *
from table
where col1 not like 'X%' order by col2
union
select *
from table
where symbol like 'X%'
but sql server doesn't allow that. Could anybody point me to the right direction or tell me that this is not possible?
PS: any LINQ solution will also be fine.
thanks
Order by whether the first character of col1 is 'X' or not, and then by col2.
Example:
SELECT *
FROM table
ORDER BY CASE WHEN col1 LIKE 'X%' THEN 1 ELSE 0 END,col2
Although, this doesn't leave the LIKE 'X%' rows unordered, neither did your example.
There is no order without an explicit ORDER BY clause. While you can use UNION to group the rows, you cannot guarantee that the order of the unordered rows is stable. See here.
The following will split the list into two groups of rows, but each will be sorted by Col1:
select Col1, Col2
from (
select Col1, Col2, 1 as PleaseSort
from MyTable
where Col1 not like 'X%'
union
select Col1, Col2, 0
from MyTable
where Col1 like 'X%' ) as PlaceHolder
order by PleaseSort desc, Col1
If you know the sort of upper limit for how many x rows you'll get then you could do something like....
select * from (select top 5000 col1 from #tmp order by col1) a
union
select col1 from #tmp

Resources