Update from another table Oracle - sql

Table1
Tripid sequence Pattern
1 1
1 2
1 3
2 1
2 2
Table2
Tripid Pattern
1 A
2 B
I'm trying to update Pattern for table 1, end result should be:
Tripid sequence Pattern
1 1 A
1 2 A
1 3 A
2 1 B
2 2 B
The code that I use:
update table1
set table1.pattern =
(select pattern from table2 where table1.tripid = table2.tripid)
where exists
(select pattern from table2 where table1.tripid = table2.tripid)
Oracle Database Error: ORA-01427: single-row subquery returns more than one row
How to do it correctly in oracle 10g?

You can use MERGE statement for this.
Query:
select * from t1
Result:
| TRIPID | SEQ | PATTERN |
|--------|-----|---------|
| 1 | 1 | (null) |
| 1 | 2 | (null) |
| 1 | 3 | (null) |
| 2 | 1 | (null) |
| 2 | 2 | (null) |
Query:
merge into t1
using t2
on (t1.tripid = t2.tripid)
when matched then update
set pattern = t2.pattern
Query:
select * from t1
Result:
| TRIPID | SEQ | PATTERN |
|--------|-----|---------|
| 1 | 1 | A |
| 1 | 2 | A |
| 1 | 3 | A |
| 2 | 1 | B |
| 2 | 2 | B |

Maybe, tripid is not unique in table2?
It is in your example, but is it unique in your real data?
DROP table table1;
create table table1(tripid number, sequence number, pattern CHAR(1));
insert into table1 values (1,1,null);
insert into table1 values (1,2,null);
insert into table1 values (1,3,null);
insert into table1 values (2,1,null);
insert into table1 values (2,2,null);
DROP table table2;
create table table2(tripid number, pattern CHAR(1));
insert into table2 values (1,'A');
insert into table2 values (2,'B');
commit;
select table2.tripid, table2.pattern from table2,table1 where table1.tripid = table2.tripid;
update table1
set table1.pattern =
(select pattern from table2 where table1.tripid = table2.tripid)
where exists
(select pattern from table2 where table1.tripid = table2.tripid);
commit;
select * from table1;
returns:
Table dropped.
Table created.
1 row created.
1 row created.
1 row created.
1 row created.
1 row created.
Table dropped.
Table created.
1 row created.
1 row created.
Commit complete.
TRIPID PATTERN
---------- -------
1 A
1 A
1 A
2 B
2 B
5 rows selected.
5 rows updated.
TRIPID SEQUENCE PATTERN
---------- ---------- -------
1 1 A
1 2 A
1 3 A
2 1 B
2 2 B
5 rows selected.
Which proves that with good data, Oracle (and your query) works perfectly.
Christian

Related

Select objects from Table A that are associated to objects in Table B ordered by matching count

This is an addition to this question:
I want to get all objects from table 1 that a have associations to item 2 or item 3, ordered by the count of matching associations.
So the result should be a list like: object 2 (2 matches), object 3 (2 matches), object 1 (1 match).
What must the SQL look like to get the results ordered?
Table 1
id | title
---------------
1 | object 1
2 | object 2
3 | object 3
Table 2
id | title
---------------
1 | item 1
2 | item 2
3 | item 3
Table 3 (n-m association)
id | object_id | item_id
------------------------------
1 | 1 | 1
2 | 1 | 2
3 | 2 | 1
4 | 2 | 2
5 | 2 | 3
6 | 3 | 2
7 | 3 | 3
Join Table1 with Table3 and aggregate as the following:
select T1.id, T1.title, count(*) matches
from table1 T1 join table3 T3
on T1.id = T3.object_id
where T3.item_id in (2, 3)
group by T1.id, T1.title
order by matches, T1.id
See demo

Update and Replace Values in one Table Column with Values from another Table Column

I have 2 tables:
id | bsi | cell
1 | 45 | NULL
2 | 23 | 600-1167
3 | 47 |
4 | 89 | 501- -
5 | 98 | 603-5670
I would like to replace cell values with data from another colum in another table matching both tables by bsi
Here is my 2nd table:
id | bsi | contact
1 | 45 | 610-5896
2 | 23 | 605-4567
3 | 47 | NULL
4 | 89 | 689-9089
5 | 98 | NULL
I would like each value in the first table replaced with the new value in 2nd table also the value where both tables match in bsi code ie to replace the NULL and '501- -' with the new value once there is one in the 2nd table.
So result should be an updated table as follows:
id | bsi | cell
1 | 45 | 610-5896
2 | 23 | 605-4567
3 | 47 | NULL
4 | 89 | 689-9089
5 | 98 | 603-5670
I have tried this query but it only replaces the new values and seems to write null values for items that are in table1 and not table2. I want to keep the table1 values that are in table 1 but not table 2.
UPDATE Table1
SET Table1.cell = Table2.Contact
FROM Table1 INNER JOIN Table1 ON Table1.bsi = Table2.bsi
Your join seems to be a little off... you aren't joining the second table
UPDATE t1
SET t1.cell = t2.Contact
FROM Table1 t1
INNER JOIN Table2 t2 ON --changed to table2
t1.bsi = t2.bsi
--where <some condition>
Also, it can be faster to just update all rows than to be selective using a where clause. See Aaron Bertrand's tests on this. I did it this way because despite you stating that I want to keep the table1 values that are in table 1 but not table 2, this wasn't reflected in your expected output. If you really do want to conditionally update them, then you need to add the where clause.
SEE DEMO HERE
create table table1 (id int, bsi int, cell varchar(16))
create table table2 (id int, bsi int, contact varchar(16))
insert into table1 values
(1,45,NULL),
(2,23,'600-1167'),
(3,47,''),
(4,89,'501- -')
insert into table2 values
(1,45,'610-5896'),
(2,23,'605-4567'),
(3,47,NULL),
(4,89,'689-9089')
UPDATE t1
SET t1.cell = t2.Contact
FROM Table1 t1
INNER JOIN Table2 t2 ON --changed to table2
t1.bsi = t2.bsi
--where <some condition>
select * from table1
RETURNS
+----+-----+----------+
| id | bsi | cell |
+----+-----+----------+
| 1 | 45 | 610-5896 |
| 2 | 23 | 605-4567 |
| 3 | 47 | |
| 4 | 89 | 689-908 |
+----+-----+----------+
It looks like your query was joining back on itself. Change the table you are joining on to be Table2 instead.
This will update only rows in Table1 that match up with rows in Table2 by the bsi value, setting the cell value to Contact
UPDATE Table1
SET Table1.cell = Table2.Contact
FROM Table1
INNER JOIN Table2
ON Table1.bsi = Table2.bsi

loop through cursor data and insert record if it does not exist [duplicate]

This question already has answers here:
Oracle insert if not exists statement
(5 answers)
Closed 6 years ago.
I have following tables:
Table1:
doc_id | item_id
------ | ------
71 | 4
------ | ------
75 | 8
------ | ------
75 | 3
------ | ------
75 | 2
------ | ------
73 | 7
Table2:
id | parent_id | parameter_id
------ | -----------|-------------
1 | 4 | 4
------ | -----------|-------------
2 | 8 | 3
------ | -----------|-------------
3 | 3 | 4
------ | -----------|------------
4 | 2 | 6
------ | -----------|------------
5 | 7 | 4
I want to insert row on Table 2 by following these steps:
Select item_ids from Table1 where document_id = 75;
For each item_id from 1. check if a record exist in Table2 where
parent_id of Table2 = item_id of Table 1 and parameter_id =4;
If the record does not exist then enter data.
While inserting it should insert into Table 2 values
(max(id)+1, parent_id of that particular record(associated Table1's item_id), 4 as parameter_id).
How do I do this? Can someone give me some hint. I am thinking to use cursor and loop through it and check if record exist. Then insert data accordingly??
DECLARE CURSOR C1
IS
SELECT * FROM table 1
WHERE DOC_ID = 75;
BEGIN
FOR EACH_RECORD IN C1 LOOP
// check for Table 2 for EACH_RECORD.CONFIG_ITEM_ID;
END LOOP;
END;
/
insert into table2
(
id,
parent_id,
parameter_id
)(
select
(select (max(id)) from table2) + rownum,
item_id,
4
from
table1
where
table1.doc_id = 75 and
not exists(select 1 from table2 where table1.item_id = table2.parent_id and table2.parameter_id = 4)
)
The Insert Query above is inserting into table2 the max(id) +1, item_id from table1 and 4 as the parameter_id where the doc_id is 75 and there doesn't exist the record in table2 where table1.item_id = table2.parent_id

select data from table 1 and get cross reference values of table 2 when table1 column name is matching with row values of column1 in table2

Table 1
id | check | status
1 | abc | 1
2 | def | 3
Table 2
Column1 | rawvalue | to_be_updated_value|
check | abc | new
status | 3 | 3333
Please help me to write select statement to get the following output in Oracle11g
Expected Output:
id | check | status
1 | **new** | 1
2 | def | **3333**
This is the first thing I think you want to do (applies to SQL Server):
SELECT ISC.COLUMN_NAME, T2.*
FROM <YourDatabase>.INFORMATION_SCHEMA.COLUMNS ISC
INNER JOIN Table2 T2
ON T2.Column1 = ISC.COLUMN_NAME
WHERE ISC.TABLE_NAME = N'Table1';

sql query distinct on multiple columns

i have this data and i am trying to find cases where there are different ids but duplicate data in Field 1,2,3,4
id field1 field2 field3 field4
==== ====== ====== ===== =======
1 A B C D
2 A B C D
3 A A C B
4 A A C B
so, in whatever way possible, in this case i want it to somehow show me:
1 & 2 are duplicates
3 & 4 are duplicates
Instead of SELECT DISTINCT, select the fields and a count of rows. Use HAVING to filter out items with more than one row, e.g:
select field1
,field2
,field3
,field4
,count (*)
from foo
group by field1
,field2
,field3
,field4
having count (*) > 1
You can then join your original table back against the results of the query.
One way to do this is to use having and group by
esben=# select * from test;
id | a | b | c | d
----+---+---+---+---
1 | 1 | 2 | 3 | 4
2 | 1 | 2 | 3 | 4
3 | 1 | 1 | 3 | 2
4 | 1 | 1 | 3 | 2
(4 rows)
esben=# select count(id),a,b,c,d from test group by a,b,c,d having count(id) >1;
count | a | b | c | d
-------+---+---+---+---
2 | 1 | 2 | 3 | 4
2 | 1 | 1 | 3 | 2
(2 rows)
This doesn't list the actual id's though, but without the actual output you want it is hard to tell you how to get about that.
SELECT *
FROM [TableName]
WHERE ID IN(SELECT MIN(ID)
FROM [TableName]
GROUP BY CONCAT(field1, field2, field3, field4))
This will return the full row for id's 1 & 3