I want to return data from duplicate rows SQL Query - oracle

I want to return data from duplicative rows
SELECT column1, column2 FROM table1
COLUMN1 COLUMN2
------- -------
CA 1
CB 2
CB 3
CC 4
CD 5
CE 6
CE 7
CE 8
CF 9
I want to return rows for 'CB' and CE. Here CB and CE has more than 1 row.

I'd code this as follows:
SELECT column1, column2 FROM table1 where column1 in ("CB", "CE")

Try this out - this query first finds out those items in column1 who appear multiple time and then extract their information.
select * from table1
where column1 in (
select column1
from table1
group by column1
having count(*) > 1
)
If you are only interested in knowing the values in column1, you could just run:
select column1
from table1
group by column1
having count(*) > 1

You Can try out this code. Basically the Query is in MySQL but you can use the same logic in Oracle Database. Here the inner subquery will find out the columns which is grouped by column1 and will return a column having a count greater than 1. The Outer query will display the rows of the column fetched by the inner query.Here I have created a table with the table name as name
SQL fiddle Added for your reference SQLCODE
select * from name where column1 in(select column1 from name
group by column1
having count(*)>1);

Related

Oracle SQL -Query result was not ordered based on Index

I have a table with 5 columns,
column1, column2, column3, column4, column5
of which column1, column2 and column3 constitute 'primary key'
temp_table
Column1 Column2 Column3 Column4 Column5
2 209 Raj Kumar K
2 27 Arvind Ram R
2 227 Mahesh Kumar M
whenever i query the table, the results would be ordered by the primary key columns even if i do not give order by in the query.
Select Column1, Column2, Column3 from temp_table;
every time i run this query i do get the result as,
Column1 Column2 Column3
2 27 Arvind
2 209 Raj
2 227 Mahesh
But at one particular instance only, the query result was not ordered by primary key columns.
The result was like below,
Column1 Column2 Column3
2 209 Raj
2 27 Arvind
2 227 Mahesh
Can somebody help to find the reason why.
even if i do not give order by in the query
You should always use an ORDER BY clause if you expect to have reproducible and deterministic ordering in a result set. You should not assume any inherent order in a SQL table, as tables are modeled after (unordered) sets. As to why the ordering changed in that one instance, perhaps the way the underlying data was being stored, or maybe cached, was different for that one instance. But in any case, use you should always use ORDER BY if you expect a certain order.
You have to use ORDER BY like :
Select Column1, Column2, Column3
from temp_table
order by Column?;
And choose the column you want. You can also have DESC and ASC in the end like :
Select Column1, Column2, Column3
from temp_table
order by Column? ASC;
For ordinates decreasing or increasing.

Oracle Merge: Update single record in base table using multiple records from source table

I have a merge query as follows:
merge into table1
using table2
on (table1.column1 = table2.column1)
when mateched then
update
set column2 = table2.column2;
Now it is giving me error like :unable to get a stable set of rows in the source tables
Now the issue is the source table, table2, is having multiple records for same column1 value and table1 is having only one record per column1 value.And I need all the table2 to update table1. can you pls help here?
" the issue is the source tabletable2, is having multiple records for same column1 value "
You need to ensure your sub-query returns only one row per value of column1. Only you know what exact business rule you need to apply, but it could be something like this:
merge into table1
using ( select column1, max(column2) as column2
from table2
group by column1 ) t2
on (table1.column1 = t2.column1)
when matched then
update
set column2 = t2.column2;
"I need all records from table2 to update table1. The reason is that I have a trigger on table1 which captures all transactions(inserts/updates) and loads to another history table. "
You can't use MERGE. In fact you're probably going to have to go procedural:
begin
for t2rec in (select column1, column2
from table2
order by column1, column2 )
loop
update table1
set column2 = t2rec.column2
where column1 = t2rec.column1;
end loop;
end;
You'll need to order the loop statement to ensure the end state of table1 is right.
Alternatively you could disable the journaling trigger and do this:
insert into table1_journal
select table1.column1
, table2.column2
from table1
join table2
on table1.column1 = table2.column1
/
Then do the MERGE or a single row update.

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.

How to copy one column data into another column in oracle

I want to copy one column data into another column without
replacing the old data. For example :
Table-1
Column1 Column2
SONY Sony Desc
Lenovo Lenovo Desc
Nokia Nokia Desc
I would like result like
Column 1 column2
SONY Sony Desc
Sony Desc
Lenovo Lenovo Desc
Lenovo Desc
Nokia Nokia Desc
Nokia Desc
I have tried my query not match
Update table1 set column1 = column2
If you want to add rows, you need to INSERT instead of UPDATE. This statement will add new rows that have the column1 value copied from column2 of another row in the table and the primary key (export_config_id) value taken from a sequence (seq_export_config_id):
INSERT INTO table1
(export_config_id, column1)
SELECT seq_export_config_id.NEXTVAL, column2 FROM table1;
If column1 has a NOT NULL constraint, or if it is has the primary key constraint, then you won't be able to insert NULL values. You need to filter out the NULL values:
INSERT INTO table1 (column1)
SELECT column2
FROM table1
WHERE column2 IS NOT NULL;

Self Join Oracle

I have a table table1 below is how the data looks like.
Column1 is my foreign key of another table.
Column1 Column2 Column3
1 A 06/MAY/14
1 A 05/MAY/14
1 B 06/MAY/14
1 B 01/JAN/00
1 A 01/JAN/00
Now i want to find distinct column1 values where it meets the following condition.
1.atleast one record where column2 should be A and column3 should be (sysdate - 1)
AND
2.atleast one record where column2 should be B and column3 should be (sysdate - 1)
Meaning alteast one A and B should have their column 3 populated with (sysdate - 1)
I have written the below query, please tell if i'm doing anything wrong.
I also want to know if i'm doing the right way of joining. The table contains around 50K records and performance should be fine i guess.
SELECT DISTINCT COLUMN1 FROM
TABLE1 A
JOIN
TABLE1 B ON (A.COLUMN1 = B.COLUMN1)
WHERE
((TRUNC(A.COLUMN3) - TRUNC(A.COLUMN3) = 0)
AND TRUNC(A.COLUMN3) = TRUNC(SYSDATE - 1)
AND TRUNC(B.COLUMN3) = TRUNC(SYSDATE - 1)
AND A.COLUMN2 = 'A'
AND B.COLUMN2 = 'B'
AND TO_CHAR(A.COLUMN3, 'DD-MON-YY') != '01-JAN-00'
AND TO_CHAR(B.COLUMN3, 'DD-MON-YY') != '01-JAN-00'
);
For performance-comparison one with subselects and group:
SELECT COLUMN1 FROM (
SELECT
COLUMN1,
COUNT(COLUMN2) CNT
FROM (
SELECT DISTINCT
COLUMN1,
COLUMN2
FROM TABLE1
WHERE TRUNCATE(COLUMN3) = SYSDATE - 1 AND
(COLUMN2 = 'A' OR COLUMN2 = 'B'))
GOUP BY COLUMN1)
WHERE CNT = 2
This should work
SELECT DISTINCT A.column1 -- Obtain distinct from A
FROM table1 A -- TableA
join table1 B -- TableB
ON A.column1 = B.column1 -- Joining them on Column1
WHERE A.column3 = SYSDATE - 1 -- Yesterdays data on Table A
AND A.column2 = 'A' -- A values
AND B.column2 = 'B'; -- B Values
Note: No distinctness in your test case. So try with a unique key.

Resources