To update CLOB column in Oracle - sql

I need to update table B with column Value with CLOB type from table A
Table A
ID Value
1001 ABC
1002 CDE
1003 ABC
1004 PWD
Table B to be updated as below:
ID - varchar2(355)
Value - CLOB
ID Value
ABC 1001!1003
CDE 1002
PWD 1004

Looks more like an INSERT, not UPDATE. Anyway, LISTAGG will help in both cases.
SQL> insert into b (id, value)
2 select a.value, listagg(a.id, '!') within group (order by a.id)
3 from a
4 group by a.value;
3 rows created.
SQL> select * From b;
ID VALUE
---------- --------------------------------------------------
ABC 1001!1003
CDE 1002
PWD 1004
SQL>

Related

nested SQL query referencing a single table is running into infinite loop

This is how my query is structured but the loop is running infinite times. I am referencing a single table twice.
with XYZ AS(SELECT a, number, c, d, 1 as level
FROM table
WHERE condition = 99999
UNION ALL
SELECT a, number, c, d, level + 1 as level
FROM table b
JOIN
XYZ AS variable
ON (variable.num = b.number)
WHERE b.condition = 99999)
SELECT *
FROM XYZ
ORDER BY level
this is the expected output
a
number
c
d
level
mno
100
abc#gmail.com
CEO
1
pqr
101
bac#gmail.com
executive
2
qrs
102
cab#gmail.com
executive
2
stu
103
def#gmail.com
manager
3
I might be miss understanding you, are you just trying to add a column called With all the data called level 2?
if so this should work
ALTER TABLE MYTABLE ADD MYNEWCOLUMN VARCHAR(200) DEFAULT 'level2'

Merge statement to remove duplicate values

I am trying to remove the duplicate entries as following
Table abc
id name service_file_id
1 abc xyz
2 vbg xyz
2 vbg xyz
3 kio xyz
3 kio xyz
4 abc yzx
5 nji yzx
6 pop yzx
Table temp_table
service_file_id file_id
xyz null
yzx file_name_1
The table abc has duplicate entries for example
id name service_file_id
2 vbg xyz
2 kio xyz
I get the information about the duplicate entries via temp table. When a file_id in temp table is null, it means I have duplicate entries for that particular serivce_file_id
Below is the code I have tried
merge `abc` t
using (
# choose a single row to delete the duplicates
SELECT distinct a.*
FROM `abc` a
left join `temp_table` b
on a.service_file_id = b.file_id
where b.file_id is not null
)
ON FALSE
WHEN NOT MATCHED BY SOURCE THEN DELETE
WHEN NOT MATCHED BY TARGET THEN INSERT ROW
I can remove the duplicate entries from the table but it also deletes the rest of the data which is not duplicate.
current output
id name service_file_id
1 abc xyz
2 vbg xyz
3 kio xyz
Desired output
id name service_file_id
1 abc xyz
2 vbg xyz
3 kio xyz
4 abc yzx
5 nji yzx
6 pop yzx
Could you please help me out here?
Thanks in advance!!
Without actually referencing the temp_table table you can delete the duplicates in your abc table just by using merge and select distinct :
merge `abc` t
using(
SELECT distinct a.*
FROM `abc` a
)
ON FALSE
WHEN NOT MATCHED BY TARGET THEN INSERT ROW
WHEN NOT MATCHED BY SOURCE THEN DELETE
Output:

Jumbling the data within the table

I have a scenario, where i have to mask the data with data within the table
let's say I have a table student_details(ID, CODE, NAME)
1 A XYZ
2 A 123
3 A QWERTY
I want the output as
1 A QWERTY
2 A XYZ
3 A 123
I want the name to be within the name list in that table
for same id I Want different name which is in the table.
select * from emp_details order by dbms_random.value;
is giving some random names which are not in list.
Can any one help me with this?
Here's one option: recalculate the ID value using ROW_NUMBER analytic function which orders rows by the hash value over concatenated name, code and id columns (that's just for example; you can pick something different).
SQL> with test (id, code, name) as
2 (select 1, 'A', 'XYZ' from dual union all
3 select 2, 'A', '123' from dual union all
4 select 3, 'A', 'QUERTY' from dual
5 ),
6 inter as
7 (select row_number() over (order by ora_hash(name || code || id)) id,
8 code, name
9 from test
10 )
11 select t.id, t.code, i.name
12 from test t join inter i on t.id = i.id;
ID C NAME
---------- - ------
1 A XYZ
2 A QUERTY
3 A 123
SQL>
If you intend to permutate selected columns in your table and leave the rest of the table unchanged, you may use a join with a key permutation table.
Assume your data as follows:
ID CODE NAME
---------- ---- ------
1001 A XYZ
1002 B 123
1004 C QUERTY
1005 A FOO
Note, that the PK is not continuous, wich is the generall case. If you have the PK a continuous sequence starting with 1, you may even simplify the solution (as proposed in other answer).
First lets define the permutation table assigning to each PK a new key in random order.
create table PERM as
with rn as (
select
id,
row_number() over (order by id) rn,
row_number() over (order by dbms_random.value) rn_new
from student)
select a.ID, b.ID ID_NEW
from rn a
join rn b
on a.RN = b.RN_NEW;
ID ID_NEW
---------- ----------
1001 1004
1002 1001
1004 1005
1005 1002
The query defines two row_number sequences, first in the order of the PK, second in random order. The final join gets the original and new (permutated) IDs.
Now to permute a selected colums is as easy as to join your table twice with the permutation table in between and choose preserved columns from the first table, the permuted columns from the second one.
select a.ID, a.code, b.name
from student a
join PERM p on a.id = p.id
join student b on p.id_new = b.id
order by a.id;
ID CODE NAME
---------- ---- ------
1001 A QUERTY
1002 B XYZ
1004 C FOO
1005 A 123
As far as you preserv the permutation table you can reconstruct the former state, if you drop it, there is no way to get the original data.

How do I not select a row from sets with null and not null in SQL?

I have tried to find this on SO.
I have a table,
id | col2 | col3
---- ---- ----
5 smith (null)
5 smith 100
12 Jackson 356
12 Jackson 400
8 Johnson (null)
9 bob 1200
In this scenario I only want the rows from a set where the same id only has one non-null. In other words, I don't want smith, I don't want Johnson. I only want Jackson and bob.
I have tried,
select * from table
where is not null a
nd not exists (select * from table where is null)
I can't get it to work.
Your statement and desired results don't quite match, but this will give you every ID that does not have a NULL value in column 3:
SELECT * FROM table
WHERE id NOT IN
(SELECT ID FROM table WHERE col3 IS NULL)
If you want records with just one non-null (which you state but your expected result doesn't match, use
SELECT * FROM table
WHERE id NOT IN
(SELECT ID
FROM table
WHERE col3 IS NOT NULL
GROUP BY ID
HAVING COUNT(id) = 1
)
You can use NOT EXISTS but include a WHERE to reference each id:
select *
from yourtable t
where col3 is not null
and not exists (select id
from yourtable d
where d.col3 is null
and t.id = d.id);
See Demo

Executing Insert into statement in SQL resulting in nulls for other columns

i am trying to use an insert into a column where the data for other columns already exists, but the data is not populating adjacent to the other columns, instead data is inserted after all the data in the table.
For example:
select * from tab1;
ID NAme Last_name
1 King
2 Queen
3 Rook
select * from tab2;
Id LastName_Name
1 Abc
2 def
3 xyz
SQL : Insert into tab1 (Last_name)
select tab2.LastName_Name from tab1,tab2, where tab1.Id=tab2.Id
Output:
Id Name Last_Name
1 King NULL
2 Queen NULL
3 Rook NULL
4 NULL Abc
5 NULL def
6 NULL xyz
But I want the data as below:
Id Name Last_Name
1 King Abc
2 Queen def
3 Rook xyz
Any work around for this? thanks in advance :)
Step2:
select * from tab1;
ID Name Id2
1 King NA
2 Queen NA
3 Rook NA
select * from tab2;
ID
1
2
3
4
5
6
I want the Output data as below:
The ID data in tab2 should populate in tab1 column (ID2) which are matching with TAB1.ID column values as below:
Id Name ID2
1 King 1
2 Queen 2
3 Rook 3
Can you please provide any query for this?
So you are wanting to UPDATE the rows in tab1 with the corresponding last names from tab2?
In which case, use an UPDATE statement instead of an INSERT:
UPDATE tab1
SET tab1.Last_name = tab2.LastName_Name
FROM tab1
JOIN tab2 ON tab1.Id = tab2.Id
You don't need an INSERT you need an UPDATE statement:
UPDATE tab1 SET tab1.Last_name = tab2.LastName_Name
FROM tab1 INNER JOIN tab2 ON tab1.Id = tab2.Id