How to insert sequential numbers in primary key using select subquery? - sql

I am reading a table A and inserting the date in Table B (both tables are of same structure except primary key data type). In Table B, Primary key is int whereas in Table A it is UniqueIdentifier.
INSERT INTO TableB
(ID, Names, Address)
(select ID, Names, Address from TableA)
Now how can i insert int type incremental value (1,2,3,so on) in TableB instead of uniqueidentifier from TableA using above script.
Help?

Why not change Table B so that the primary key is an identity which auto-increments?

Go to the table properties, select the ID field, under "Identity specification", set "Identity Increment" = 1, "Identity Seed" = 1. By doing that, the ID becomes auto incremental...
Then your insert statement would be something like:
INSERT INTO TableB (Names, Address) (select Names, Address from TableA)

If changing the schema of your TableB is not an option then add a rank to your select statement like this:
insert into tableB select rank() over(order by id), name, address from tableA
This will always start at 1. I you could add + 10 if you wanted to start your numbering at a number other than 1. I'm sure you get the idea from there.

CREATE TABLE TableB
(
ID int PRIMARY KEY IDENTITY(1,1),
Name nvarchar(200),
Address nvarchar(200)
)
Then, in the query, don't specify the value of the identity column.
INSERT INTO TableB(Name, Address)
SELECT Name, Address FROM TableA

Related

Typo in a column name inside a sub-query, but no "Invalid column name" error

I have a table, let's call it A. I want to delete rows with IDs 1 and 2 from that table. For that, I created a table variable #B, containing values 1 and 2 but that column I will name PK.
Now I do this:
DELETE FROM A
WHERE ID IN (
SELECT ID
FROM #B
)
Notice my (deliberate) programming error. In the sub-select, I have used a wrong column name. Accidentally it is the same name used in table A.
This should result in an 'invalid column name' error, right? Except it does not. It executes. Not only that, all data from table A gets deleted. As if there is no more predicate.
I have created a full demo script:
-- What happened to my data???
IF OBJECT_ID('tempdb..#JustATable') IS NOT NULL
DROP TABLE #JustATable
CREATE TABLE #JustATable (
PK INT NOT NULL PRIMARY KEY IDENTITY(1, 1),
ID INT NOT NULL,
NOTE VARCHAR(100) NOT NULL
)
INSERT INTO #JustATable (ID, NOTE)
SELECT database_id, DB_NAME(database_id)
FROM sys.databases;
SELECT NULL [inserted all the rows from sys.databases into the temptable], *
FROM #JustATable;
DECLARE #JustATableVariable TABLE (
PK INT NOT NULL PRIMARY KEY IDENTITY(1, 1),
ID_2 INT NOT NULL,
NOTE VARCHAR(100) NOT NULL
)
INSERT INTO #JustATableVariable (ID_2, NOTE)
SELECT database_id, DB_NAME(database_id)
FROM sys.databases
WHERE database_id = 2;
SELECT NULL [this is my table variable data], *
FROM #JustATableVariable;
DELETE FROM #JustATable
WHERE ID IN (
SELECT ID_2
FROM #JustATableVariable
);
SELECT NULL [I have just removed tempdb from the temptable], *
FROM #JustATable;
DELETE FROM #JustATable
WHERE ID IN (
SELECT ID /* this is the wrong column name but the same name as used in the temptable column */
FROM #JustATableVariable
);
SELECT NULL [wait...where is my data?], *
FROM #JustATable;
Can someone explain to me what is going on here? Has anyone seen this behavior before? Could this be a bug?
In the subquery ... (select id from #b) the column id is not fully qualified. So according to SQL specs, the RDBMS will first see if id column exists in table #b. If it does not, it will search "upwards" until it finds the id column in table a. The query is effectively identical to:
delete from a where id in (select a.id from #b)
Syntactically correct, semantically wrong.

Generate ID for duplicate values in sql server

I found following link to assign identical ID to duplicates in SQL server,
my understanding there is no sql server function to automatically generate it rather than using insert and update queries in link attached, is that statement True, if yes, then what would be the trigger if for example someone insert data to MyTable then run insert and update query from link:
Assign identical ID to duplicates in SQL server
INSERT INTO secondTable (word) SELECT distinct word FROM MyTable;
UPDATE MyTable SET ID = (SELECT id from secondTable where MyTable.word = secondTable.word)
thanks,
S
Is this what you want? I can't think of an "automatic" solution that would just increase the Id for new words.
CREATE TABLE MyTable (
Id INT NOT NULL,
Word NVARCHAR(255) NOT NULL
PRIMARY KEY (Id, Word)); -- primary key will make it impossible to have more than one combination of word and id
DECLARE #word NVARCHAR(255) = 'Hello!';
-- Get existing id or calculate a new id
DECLARE #Id INT = (SELECT Id FROM MyTable WHERE Word = #word);
IF(#id IS NULL) SET #Id = (SELECT MAX(Id) + 1 FROM MyTable);
INSERT INTO MyTable (Id, Word)
VALUES (#id, #word)
SELECT * FROM MyTable
If you can't for some reason have id and word as a combined primary key, you may use an unique index to make sure that there is only one combination

How to split data in SQL Server table row

I have table of transaction which contains a column transactionId that has values like |H000021|B1|.
I need to make a join with table Category which has a column CategoryID with values like H000021.
I cannot apply join unless data is same.
So I want to split or remove the unnecessary data contained in TransctionId so that I can join both tables.
Kindly help me with the solutions.
Create a computed column with the code only.
Initial scenario:
create table Transactions
(
transactionId varchar(12) primary key,
whatever varchar(100)
)
create table Category
(
transactionId varchar(7) primary key,
name varchar(100)
)
insert into Transactions
select'|H000021|B1|', 'Anything'
insert into Category
select 'H000021', 'A category'
Add computed column:
alter table Transactions add transactionId_code as substring(transactionid, 2, 7) persisted
Join using the new computed column:
select *
from Transactions t
inner join Category c on t.transactionId_code = c.transactionId
Get a straighforward query plan:
You should fix your data so the columns are the same. But sometimes we are stuck with other people's bad design decisions. In particular, the transaction data should contain a column for the category -- even if the category is part of the id.
In any case:
select . . .
from transaction t join
category c
on transactionid like '|' + categoryid + |%';
Or if the category id is always 7 characters:
select . . .
from transaction t join
category c
on categoryid = substring(transactionid, 2, 7)
You can do this using query :
CREATE TABLE #MyTable
(PrimaryKey int PRIMARY KEY,
KeyTransacFull varchar(50)
);
GO
CREATE TABLE #MyTransaction
(PrimaryKey int PRIMARY KEY,
KeyTransac varchar(50)
);
GO
INSERT INTO #MyTable
SELECT 1, '|H000021|B1|'
INSERT INTO #MyTable
SELECT 2, '|H000021|B1|'
INSERT INTO #MyTransaction
SELECT 1, 'H000021'
SELECT * FROM #MyTable
SELECT * FROM #MyTransaction
SELECT *
FROM #MyTable
JOIN #MyTransaction ON KeyTransacFull LIKE '|'+KeyTransac+'|%'
DROP TABLE #MyTable
DROP TABLE #MyTransaction

Insert into first row when the table has a primary key set

I spent all day creating then manually inserting into some tables I created today that look like this:
ID - Int (Primary Key set to Auto Increment)
Value - Varchar
But then I realized I had forgotten to insert a value of "--" into the first row of each table.
Is it possible to maybe add 1 to the ID no for each of the values currently in the table then insert the "--" value into the first row?
One of the ways to fix it is to update the record with the ID=1 to '--':
update yourTable set Value = '--' where id = 1
Then you will be required to re-insert the first record into the table:
INSERT INTO yourTable (Value)
VALUES('the value that was originally inserted as 1')
However, if the order of the already inserted records is important then you can insert the '--' value as the ID = 0. In this case you need to disable the IDENTITY column using the SET IDENTITY_INSERT:
SET IDENTITY_INSERT yourTable ON
INSERT INTO yourTable (ID, Value)
VALUES(0, '--')
SET IDENTITY_INSERT yourTable OFF
This way the order of inserted records will be preserved and the '--' will be inserted with the ID of 0
BTW, for mySQL you can insert into the IDENTITY column by default
Because Your ID column auto increment (IDENTITY), when you insert, you mustn't insert ID column. To insert your table, you just insert other columns.
Code insert like this:
INSERT INTO Your_Table (ColA, ColB, ...) -- `except identity colums`
VALUES (A, B, ...)
INSERT INTO Your_Table
VALUES (A, B, ...) -- except identity colums
INSERT INTO Your_Table
SELECT ColA, ColB, ... FROM Other_Table -- except identity colums
If Your_Table empty:
INSERT INTO Your_Table (Value)
VALUES ('--')
INSERT INTO Your_Table
SELECT '--'
If not:
UPDATE Your_Table
SET Value = '--'
WHERE ID = 1
------------------------ More Infor -------------------------------------------
If you want to first row have ID = 1. You can set ID column have IDENTITY(1,1). Like this:
CREATE TABLE Your_Table
(
ID INT IDENTITY(1, 1) PRIMARY KEY,
Value VARCHAR(50) NULL
)
Or, After you create Your_Table, you can set right-click Your_Table, select Design, select ID column. Look Column Properties below, expand Identity Specification, Double click (Is identity), then set value Identity Increment and Identity Seed

Use autogenerated column to populate another column

How can I use an auto-generated column to populate another column during an INSERT statement?
Long story short: we are reusing a database table and an related ASP page to display completely different data than was originally intended.
I have a table similar in structure to the following. It's structure is out of my control.
ID int NON-NULL, IDENTITY(1,1)
OrderNo varchar(50) NON-NULL, UNIQUE
More ...
The table has been repurposed and we are not using the OrderNo column. However, it's NON-NULL and UNIQUE. As dummy data, I want to populate it with the row's ID column.
I have the following SQL so far, but can't work out how to use the row's generated ID.
INSERT INTO MyTable (OrderNo, More)
OUTPUT INSERTED.ID
VALUES (CAST(ID AS varchar(50)))
This just gives:
Msg 207, Level 16, State 1, Line 3
Invalid column name 'ID'.
Here's a solution using the OUTPUT clause. Unfortunately, you won't be able to do it in a single statement.
CREATE TABLE Orders (
ID int not null identity(1,1),
OrderNo varchar(50) not null unique
)
CREATE TABLE #NewIDs ( ID int )
INSERT Orders (OrderNo)
OUTPUT INSERTED.ID INTO #NewIDs
SELECT 12345
UPDATE o
SET o.OrderNo = i.ID
FROM Orders o
JOIN #NewIDs i
ON i.ID = o.ID
SELECT * FROM Orders
One option would be:
create trigger YourTable_Trigger
on YourTable
INSTEAD OF INSERT
as begin
INSERT INTO YourTable (OrderNo, AnotherField)
SELECT 0, AnotherField FROM Inserted
UPDATE YourTable SET OrderNo = SCOPE_IDENTITY() WHERE ID = SCOPE_IDENTITY()
end;
And here is the Fiddle.
Good luck.