Insert values for whole column in SQL Server - sql

Is there any way to insert different values for specific column, not whole row in SQL Server.
Classic UPDATE SET would set all to same value.
For example I want to set some int values to Ranking column for each of 3 rows, without dropping them and doing complete new insert into.

Use row_number()
update a set ranking =rn from tablename a join
(select id,name, row_number() over(order by id) as rn
from tablename) b on a.id=b.id

do update
update tabale
set ranking= your_va
with cte as
(
select * ,row_number() over(order by id) rn
) update cte set ranking=rn where id<=3

What value do you want to set ranking to?
Just any value:
update mytable set ranking = id;
Certain values:
update mytable set ranking =
case name
when 'Positive' then 1
when 'Neutral' then 2
when 'Negative' then 3
else 4
end;

Related

SQL sequence updating column in reverse order

I'm trying to update a column cohort_number in a table with sequential values from 1 to x (in this case 42) using a seq as below.
CREATE SEQUENCE seq start with 1 increment by 1 no maxvalue no cycle
UPDATE t1
SET cohort_number = next value for seq, instance_number = x.instanceNumber
FROM
(
SELECT id,
1 instanceNumber
FROM t1
) x
DROP SEQUENCE seq
However on update rather than the first row cohort_number = 1, second row = 2 and so on, the first row cohort_column = 42, second row cohort_column = 2. I.e it appears that the update is being processed from the last entry in the select result rather than the first. Is there anyway around this?
I've also tried with ROW_NUMBER as below, but every value for the cohort_column is set to 1, which I believe is due to id having no duplicate values (but I'm guessing here)
UPDATE t1
SET cohort_number = x.cohort_number, instance_number = x.instance_number
FROM
(
SELECT id,
ROW_NUMBER() over (order by id) as cohort_number,
1 instance_number
FROM t1
) x
The strange and proprietary UPDATE ... FROM syntax makes my head hurt.
This:
UPDATE t1
SET cohort_number = x.cohort_number, instance_number = x.instance_number
FROM
(
SELECT id,
ROW_NUMBER() over (order by id) as cohort_number,
1 instance_number
FROM t1
) x
Doesn't work, because you're updating T1, without correlating it with x, and your're not updating x. Either would work.
I find it much easier to write a SELECT query that returns all the rows that will be updated, along with the new values for columns to be updated. Then update that:
with x as
(
SELECT id,
cohort_number
instance_number,
ROW_NUMBER() over (order by id) as new_cohort_number,
1 new_instance_number
FROM t1
)
update x set cohort_number = new_cohort_number, instance_number = new_instance_number
Why would you use a sequence for this? Just use row_number():
UPDATE toupdate
SET cohort_number = seqnum,
instance_number = new_instanceNumber
FROM (SELECT t1.*, ROW_NUMBER() OVER (ORDER BY id DESC) as seqnum
1 as new_instanceNumber
FROM t1
) toupdate;

Oracle: UPDATE with ORDER BY [duplicate]

I want to populate a table column with a running integer number, so I'm thinking of using ROWNUM. However, I need to populate it based on the order of other columns, something like ORDER BY column1, column2. That is, unfortunately, not possible since Oracle does not accept the following statement:
UPDATE table_a SET sequence_column = rownum ORDER BY column1, column2;
Nor the following statement (an attempt to use WITH clause):
WITH tmp AS (SELECT * FROM table_a ORDER BY column1, column2)
UPDATE tmp SET sequence_column = rownum;
So how do I do it using an SQL statement and without resorting to cursor iteration method in PL/SQL?
This should work (works for me)
update table_a outer
set sequence_column = (
select rnum from (
-- evaluate row_number() for all rows ordered by your columns
-- BEFORE updating those values into table_a
select id, row_number() over (order by column1, column2) rnum
from table_a) inner
-- join on the primary key to be sure you'll only get one value
-- for rnum
where inner.id = outer.id);
OR you use the MERGE statement. Something like this.
merge into table_a u
using (
select id, row_number() over (order by column1, column2) rnum
from table_a
) s
on (u.id = s.id)
when matched then update set u.sequence_column = s.rnum
UPDATE table_a
SET sequence_column = (select rn
from (
select rowid,
row_number() over (order by col1, col2)
from table_a
) x
where x.rowid = table_a.rowid)
But that won't be very fast and as Damien pointed out, you have to re-run this statement each time you change data in that table.
First Create a sequence :
CREATE SEQUENCE SEQ_SLNO
START WITH 1
MAXVALUE 999999999999999999999999999
MINVALUE 1
NOCYCLE
NOCACHE
NOORDER;
after that Update the table using the sequence:
UPDATE table_name
SET colun_name = SEQ_SLNO.NEXTVAL;
A small correction just add AS RN :
UPDATE table_a
SET sequence_column = (select rn
from (
select rowid,
row_number() over (order by col1, col2) AS RN
from table_a
) x
where x.rowid = table_a.rowid)

sql server duplicate ID's update other columns

I was working on a task to update columns which have duplicate ID's in a column
how can we update column only DrugLabelName ? i need to update old_drug_name with new_drug_name using the duplicate ID 00004029830 ?
Please advise
If you want all rows with the same id to have the same name, you can use window functions:
with toupdate as (
select t.*,
first_value(druglabelname) over (partition by id order by intid desc) as new_druglabelname
from t
)
update toupdate
set druglabelname = new_druglabelname
where druglabelname <> new_druglabelname;
How about?
CREATE TABLE tbl
(INTid int
,ID varchar (20)
,DrugLabelName varchar(200)
)
INSERT tbl (INTid, ID, DrugLabelName)
SELECT 137272, '00004029830', 'old_drug_name'
INSERT tbl (INTid, ID, DrugLabelName)
SELECT 1668177, '00004029830', 'New_drug_name'
INSERT tbl (INTid, ID, DrugLabelName)
SELECT 1668178, '00004029831', 'Other_drug_name'
GO
UPDATE t
SET DrugLabelName = x.DrugLabelName
FROM tbl AS t
INNER JOIN tbl as x
ON t.ID = x.id
AND x.INTid > t.INTid
SELECT *
FROM tbl
DROP TABLE tbl

Using UPDATE to insert a value returned by a SELECT statement

I have a table where I want to update a column with the value in another column in the previous row.
I want to do something like this.
UPDATE myTable as b SET prev=(SELECT top 1 myField FROM myTable
WHERE rowID<b.rowID ORDER By rowID Desc)
Any ideas?
Note: I'm using Access/SQL server. I am getting an error 'operation must use an updatable query'.
Note2: The solution from How do I UPDATE from a SELECT in SQL Server? doesnt work.
You can achieve this with a combination of the LAG() analytic function to compute the value of for the previous row and an UPDATE (here, I'm using a MERGE statement):
MERGE INTO mytable as target using (
select
t.id,
lag(field1) over (partition by null order by id) new_prev_field
from mytable t
) as src (id, new_prev_field)
on (target.id = src.id)
when matched
then update
set prev_field1 = src.new_prev_field;
SQL Fiddle
Instead of Top, use Max()
UPDATE myTable as b
SET prev = (
SELECT max(rowID)
FROM myTable
WHERE rowID < b.rowID)

Incrementing int column in MS SQL Server table via SP

Is there a T-SQL statement to auto fill an empty column in a table with incremented values starting at one specific value?
E.g.
UPDATE A SET A.NO = ROW_NUMBER() OVER (ORDER BY A.NO) + #max WHERE A.NO is NULL
This statement doen't work and I don't know how to make it run...
Any help is appreciated!
WITH q AS
(
SELECT a.*, MAX(no) OVER() + ROW_NUMBER() OVER (ORDER BY a.no) AS rn
FROM a
)
UPDATE q
SET no = rn
This works. You need to decouple the ranking function from the update
UPDATE
bar
SET
NO = bar.foo + #max
FROM
(SELECT
A.NO,
ROW_NUMBER() OVER (ORDER BY A.NO) AS foo
FROM
A
WHERE
A.NO is NULL
) bar