I have a table which in which I would like to generate random numbers in a specific format (e.g. TEST-10256). For which I have been using the below:
concat('TEST-' , uniform(10000, 99000, RANDOM()))
However I now want to update a table with these random numbers based on two columns, so the desired outcome would be this:
I am not sure how to keep the same random value per previously matching it on the same values in ROW1 & ROW2.
Based on query from #Lukasz, we can use update statement.
-- Original
select * from test;
ROW1
ROW2
A
12
A
12
B
5
B
5
C
1
C
1
D
10
-- Update statement
update test t set t.row2 = t1.new_col
from (select row1, row2,
CONCAT('TEST-' , uniform(10000, 99000, RANDOM())) new_col
from (select distinct row1, row2 from test)
)t1
where t1.row1 = t.row1
and t1.row2 = t.row2;
-- After update
select * from test;
ROW1
ROW2
A
TEST-37642
A
TEST-37642
B
TEST-39082
B
TEST-39082
C
TEST-50195
C
TEST-50195
D
TEST-14564
Step 1: Generate a temporary table for possible values:
CREATE OR REPLACE TEMPORARY TABLE random_values
AS
SELECT ROW1, ROW2, CONCAT('TEST-' , uniform(10000, 99000, RANDOM())) AS new_value
FROM (SELECT DISTINCT ROW1, ROW2 FROM <table_name>) AS sub;
Step 2: Join using the newly generated and materialized values:
SELECT t.ROW1, rv.new_value AS ROW2
FROM <table_name> t
JOIN random_values rv
ON t.ROW1 = rv.ROW1
AND t.ROW2 = rv.ROW2;
Output:
Try using the MERGE statement to populate your new field. It allows you to fully run your query then apply its results as an UPDATE.
You can get the syntax here
Related
I want to generate unique ids based on what the value of a certain row is:
I have row1 and I want to generate new unique values based on row. Please see example below:
ROW 1 ROW2
====== =====
A101517 --> 68F66F3A-616B-45AA-B0EE-AC1B01040596
A101517 --> 68F66F3A-616B-45AA-B0EE-AC1B01040596
A233446 --> 56B79D73-0DBC-4EDA-8F8A-A76300C741AB
A233446 --> 56B79D73-0DBC-4EDA-8F8A-A76300C741AB
A233446 --> 56B79D73-0DBC-4EDA-8F8A-A76300C741AB
A110027 --> 3EF0A1B5-B634-4549-9227-AA0F014040A2
Current solution:
UPDATE ROW2 SET ROW2 = NEWID();
THis is generating new values for each record. I want the same newid() when matching row1.
You could do an update join from your table to a CTE which generates single GUID value for each distinct ROW1 value.
WITH cte AS (
SELECT DISTINCT ROW1, NEWID() AS ROW2
FROM yourTable
)
UPDATE t1
SET ROW2 = t2.ROW2
FROM yourTable t1
INNER JOIN cte t2
ON t2.ROW1 = t1.ROW1;
Using SQL Server 2012.
The table I'm working with is shown below, along with code for the query. When I find ReasonString_S = 'Fault Reset' I would like to add that rows DurationMinutes_D to the next row and delete the current row.
I think a case when statement would work but I kept getting syntax issues and I'm fairly new to sql queries.
select ROW_NUMBER() OVER (ORDER BY EntryDate_T) AS Row, e.equip_name,
ReasonString_S, DurationMinutes_D, rt.Name_S ProcStateString, EntryDate_T
into #temptable
from AT_PM_PlantStateEvent pse
inner join EQUIPMENT e on pse.OwnerKey_I = e.equip_key
inner join dbo.AT_PM_ReasonTree rt on pse.ReasonKey_64 = rt.atr_key
where EntryDate_T >= #jobstart and EntryDate_T < #jobend
and rt.Name_S <> 'Running'
and e.equip_name = #mach
Thanks for the help!
It seems Row is your identity column if not then don't hesitate to create or use another existing one. It has many benefits as it's very useful in your case you can perform the desired operation with the help of that simply using JOIN as below:
create table #test(rowNum int identity(1,1),
ReasonString_S varchar(50),
DurationMinutes_D float)
insert into #test values
('Model1',0.34),
('Model2',0.35),
('Model3',0.36)
DATA:
rowNum ReasonString_S DurationMinutes_D
-----------------------------------------
1 Model1 0.34
2 Model2 0.35
3 Model3 0.36
update t set t.ReasonString_S = u.DurationMinutes_D
from #test t
left join #test u on u.rowNum = t.rowNum+1
OUTPUT:
rowNum ReasonString_S DurationMinutes_D
-----------------------------------------
1 0.35 0.34
2 0.36 0.35
3 NULL 0.36
Here's a general answer. To update a row based on the value in the next row, you should use the LEAD function. First you need to identify which column you want to sort by in order to determine which row is the next row. LEAD lets you get the value of a particular column from the next row. If you write a subquery using the LEAD function (which can only appear in the SELECT or ORDER BY clause), you can update by joining to the subquery.
Conversely, to update a row based on the value in the previous row, you'd use the LAG function.
Here's an example:
declare #t1 table (id int, val varchar(10))
insert into #t1 values (1, 'val1')
insert into #t1 values (2, 'val2')
insert into #t1 values (3, 'val3')
update #t1 set val = sq.next_row_val
from #t1 t1
inner join (
select t1.id, LEAD(t1.val) over (order by t1.id) as next_row_val
from #t1 t1
)sq on t1.id = sq.id
select * from #t1
id val
1 val2
2 val3
3 NULL
I've a table like this
ID col1 col2 col3 col4
---------------------------------------------------
1 a b c d
2 e f g h
So if I pass the ID 2 it should return all the colum values as separate rows as this
Colum Value
---------------------
ID 2
Col1 e
col2 f
col3 g
col4 h
So all the cells of that single rows been splitted as separate rows.
How can I accomplish this
One way to do it with unpivot and union all.
select 'id' as colu,cast(id as varchar(255)) as val from t where id=2
union all
select colu,val
from t
unpivot (val for colu in (col1,col2,col3,col4)) u
where id=2
You can use cross apply as below:
Select Id as [Column], [Value] from yourcols
cross apply (values(col1), (col2), (col3), (col4)) rws([Value])
where Id = 2
Please refer the below stack over flow link SQL query to split column data into rows
found the question identical as yours.
I'm working on pulling data to a table which has two data sets of data loaded to temp table and finally inserts into table. There are 2 records which are duplicates but i need both the records if their value on one column is same else delete it. Col1 and col4 are primary keys
col1 col2 col3 col4
--------------------
a ab abc x
a ab abc y
b ab abc y
b ab abc z
what i want is forget about col 2 and col3, check in col1 if row 1 and row 2 are same it should go check col4 and if row1 and row 2 are different it should display both row1 and row 2 even if row 2 and row 3 in col4 are same. so if the records are as i mentioned it should allow all 4 values but with the logic i wrote it is returning row1,row3,row4 because it is considering row2 and row3 of col 1 with row 2 row 3 of col 4 and displaying only 3 records but i want all records. Please help me how to write a logic in sql for this situation.
Based on what I have understood from your question, you could do something like this..
DELETE i
FROM YourTable i INNER JOIN
(
SELECT col1,col4
FROM YourTable
GROUP BY col1,col4
HAVING count(col2)>1
) t ON t.col1 = i.col1 AND t.col4 = i.col4
Live Demo Here
Or if ou want to keep only one record and remove other duplicate records, you could do like this..
;with cte as
(
SELECT *,row_number() over(partition by col1,col4 order by col1,col4) as rn
FROM YourTable
)
DELETE from cte where rn>1
Live Demo Here
I have following structure of data in Oracle table
COL1 COL2 COL2 GRP_ID
A A B 1
A A B 1
A A C 2
A A B 1
A D E 3
A D E 3
F G H 4
F G H 4
Basically each unique combination of col1, col2 and col3 has different value in GRP_ID column.
I need to replace value in GRP_ID column with database sequence value such that (assuming next value of sequence is 235678):
COL1 COL2 COL2 GRP_ID
A A B 235678
A A B 235678
A A C 235679
A A B 235678
A D E 235680
A D E 235680
F G H 235681
F G H 235681
There are millions of records in the table so I do not want to go through a loop. Reason to use database sequence is that the number provided by sequence will be exposed to customer and therefore it should not repeat when next communication is sent to customer.
Is there a way to do this through SQL?
Thanks!
Don't know if is the fastest way but it works.
CREATE FUNCTION NEXT
RETURN NUMBER IS
v_nextval NUMBER;
BEGIN
v_nextval := NEW_SEQUENCE.nextval;
RETURN(v_nextval);
END;
/
UPDATE EXAMPLE
SET EXAMPLE.GroupID =
(
SELECT G.GroupID FROM
(
SELECT B.Column1, B.Column2, B.Column3, MY_SCHEMA.NEXT() AS GroupID
FROM EXAMPLE B
GROUP BY B.Column1, B.Column2, B.Column3
) G
Where G.Column1 = EXAMPLE.Column1 AND G.Column2 = EXAMPLE.Column2
AND G.Column3 = EXAMPLE.Column3);
SELECT *
FROM EXAMPLE
Basically you have to do a distinct or group by to get all the different groups that you have and use the sequence in a function or you will get the sequence number is not allowed here error from oracle and then do an update.
See complete example on sqlfiddle
http://sqlfiddle.com/#!4/bf261/8
How about:
begin transaction
Get next sequence in a temp var
Disable sequence
update tablename set grp_ID = grp_ID + tmpVar-1
Select into tempVar max(grp_ID) from tableName
Re-seed sequence based value now in tempvar+1
Re-enable sequence
commit and end transaction
But i'm confused by something when you add additional records later, they can't simply do sequence.nextval because it's only needed when col1,col2,col3 doesn't already exist, otherwise it should use the group_ID for that unique combination... just seems odd, doable but odd.