Add Row number to a new column - sql

I want to create a new column and populate the value of each row in that column with the row number.
This could be achieved in oracle by doing this.
alter table mytable add (myfield integer);
update mytable set myfield = rownum;
How would this be done in SYBASE ASE?

alter table mytable
add id bigint identity not null
That's all. There will be a column id in every row that contains a unique sequence number for that row.

create column table some_names
(ID bigint not null primary key generated by default as IDENTITY,
NAME nvarchar(30));
And now we can do things like this:
insert into some_names (name) values ('Huey');
insert into some_names (name) values ('Dewey');
insert into some_names (name) values ('Louie');

In my case when I tried to do it with identity column time it wasn't able to finish in reasonable time (196400 rows).
Fast and easy way was to create an INT column and fill it up using a temporary variable #id incremented after each row.
This solution finished in ~4 seconds.
alter mytable add myfield INT
DECLARE #id INT
SET #id = 0
UPDATE mytable
SET #id = myfield = #id + 1
You can find more info here: https://www.mssqltips.com/sqlservertip/1467/populate-a-sql-server-column-with-a-sequential-number-not-using-an-identity/

Related

How to get sequence start value from another table's max value

I'm trying to insert a bunch of values in a table but it doesn't have IDENTITY column, and I need to insert a unique value in that field.
And the sequential number should be start based on the previous value present in that same field.
lets say I have a table like this
create table testTable (id int, fieldA varchar (20))
insert into testTable
values (6,'Nick'),(7,'Tom')
Now the next value I insert in ID field should take be 8 and next row should be 9 and so on...
And below is the sequence I created; and is not working
CREATE SEQUENCE testTable_seq
declare #maxy int = ((select max(ID) from testTable) + 1)
START WITH #maxy
INCREMENT BY 1
I expect the below insert should get the next value from the sequence I created or just tto get the next sequential number from previous ID field
insert into testTable
values (testTable_seq.next value,'Harry')
You can't do that, if you see the arguments in the docs CREATE SEQUENCE it already stated that the value of START WITH should be a constant value, same as INCREMENT BY, MINVALUE and MAXVALUE
START WITH constant
I don't understand why you want to create a SEQUENCE to insert values into a table, and also MAX() won't do as you expect, instead you can simply
CREATE TABLE TestTable(
ID INT IDENTITY(1, 1) NOT NULL,
AColumn VARCHAR(20),
CONSTRAINT PK_TestTable_ID PRIMARY KEY(ID)
);

Assistance with an auto increment primary key

I'm adding a row to a SQL Server table that has the primary key column as auto increment (identity). When I insert a new row into the table programmatically, is there a way to get the value of the key of the row that was added, as I want to use that as a foreign key in another related table?
You can use the OUTPUT clause.
INSERT INTO YourTable (SomeInteger)
OUTPUT INSERTED.IncrementedColumn
VALUES (1)
This is how I do it:
DECLARE #lastId int
INSERT INTO ...
SET #lastId = SCOPE_IDENTITY();
select #lastId

SQL insert ID from IDENTITY ID of the row being inserted

I would like to know, if there is a direct way to insert ID (generated at ID column with IDENTITY(1,1)) to another columns.
In another words, I am looking for SCOPE_IDENTITY() I could get at the time of inserting, not after the INSERT is commited.
I have a table, where there is a column with secondary ID (SID), which references rows from the same table and in some special cases it references itself.
The only way I know to do that is to do the INSERT and consequently UPDATE SID in those cases. Simplified example:
DECLARE #ID INT
INSERT INTO Table (SID) VALUES (NULL);
SELECT #ID = SCOPE_IDENTITY();
UPDATE Table SET SID = ID WHERE ID = #ID;
There are some glitches, i.e. due to the fact that the row may or may not reference itself, etc.
You can do this with an AFTER INSERT trigger. In case of self-reference, leave the column NULL and have the trigger set the column equal to the IDENTITY column.
In pseudo:
Join the table with inserted, filter where SID is NULL
For those rows, update the table and set SID = ID
If it is not possible to use the NULL value, in cases where it should be possible to have no reference at all, you can use another stub value. E.g. -1 if the IDs will always be positive. In that case, apply the above way of working and substitute NULL with -1.

Inserting a new column for serial number

I have table with 500 records in it and want to insert new column as "serial number" starting with 1.
If you care about the order in which the identity values are assigned, you are best off doing this:
CREATE TABLE dbo.NewTable
(
SerialNumber INT IDENTITY(1,1),
... other columns from original table ...
);
INSERT dbo.NewTable(...other columns...)
SELECT ...other columns...
FROM dbo.OriginalTable
ORDER BY ...ordering criteria...
OPTION (MAXDOP 1); -- to prevent parallelism from messing with identity
DROP TABLE dbo.OriginalTable;
EXEC sp_rename N'dbo.NewTable', N'OriginalTable', N'OBJECT';
You may have to deal with constraints etc. and you will want to do this in a transaction. The point is that just adding an identity column to the table with assign the identity values in an arbitrary order. If you don't care about how the existing values are assigned serial numbers, then just use Kyle's answer.
This could be achieved as follows:
alter table YourTable
add SrNo int identity(1,1)
in PostgreSQL just do:
ALTER TABLE ttaabbllee ADD COLUMN columnName serial NOT NULL; and done!..

Update value on insert into table in SQL Server

I am working with SQL Server - on inserting into a table, I have a unique constraint on a table column id. There is a possibility that when inserting, the value going into the id column is 0. This will cause an error.
Is it possible to update this id to another value during the insert if the id value is 0? This is to prevent the error and to give it a valid value.
Possibly a trigger?
A trigger is one way, but you may want to use a filtered index (CREATE UNIQUE INDEX, not as a table constraint) to ignore zero value. This way, you don't have to worry about what value to put there
Alternatively, if you want to populate it from another column, you can have a computed column with a unique constraint.
ALTER TABLE whatever
ADD ComputedUniqueCol = CASE WHEN Id = 0 THEN OtherCol ELSE Id END
If that's your primary key you can specify it as IDENTITY. Then it should generate a value for itself based on seed and increment (the default is seed=1 and default=1) so you don't have to worry about it.
CREATE TABLE MyTable
(
ID int PRIMARY KEY IDENTITY,
...
)
create an "instead of" trigger and check for the value on the ID.
CREATE trigger checkID
on YOUR_TABLE
instead of insert
as
begin
declare #id int
select #id=id from inserted
if (#id==0) begin
--DO YOUR LOGIC HERE AND THEN INSERT
end else begin
insert into DESTINATION_TABLE (VALUES)
SELECT VALUES FROM INSERTED
end
end