I've deleted some records (more precisely row 4) from a table in a SQL Server database. Now the first column goes like this (1,2,3,5) without row 4:
ID Name
------------
1 Luk
2 Sky
3 Philips
5 Andrey
How can I recreate this table and insert all data again in appropriate order?
Like this:
ID Name
--------
1 Luk
2 Sky
3 Philips
4 Andrey
EDIT:
But if i have another column (number) that is not a key, like this:
ID Number Name
------------
1 1 Luk
2 2 Sky
3 3 Philips
5 5 Andrey
Then can i recreate column Number and Name,
ID Number Name
------------
1 1 Luk
2 2 Sky
3 3 Philips
5 4 Andrey 'Can i do this, and if can HOW?
I would make a pretty strong case for never storing this number, since it is calculated, instead you could just create a view:
CREATE VIEW dbo.YourView
AS
SELECT ID,
Number = ROW_NUMBER() OVER(ORDER BY ID),
Name
FROM dbo.YourTable;
GO
This way after you have deleted rows, your view will already be in sync without having to perform any updates.
If you need to store the value, then almost the same query applies, but just placed inside a common table expression, which is then updated:
WITH CTE AS
( SELECT ID,
Number,
NewNumber = ROW_NUMBER() OVER(ORDER BY ID)
FROM dbo.YourTable
)
UPDATE CTE
SET Number = NewNumber;
You can use dbcc command
DBCC CHECKIDENT('tableName', RESEED, 0)
It would reset identity to 0.
Note it would require to truncate table first.
You can make the ID to auto increment which by default, the starting value for AUTO_INCREMENT is 1, and it will increment by 1 for each new record.
E.g MSSQL uses IDENTITY keyword to auto increment whereas MySQL uses the AUTO_INCREMENT keyword to perform an auto-increment feature.
MSSQL
ID int IDENTITY(1,1) PRIMARY KEY
MySQL
ID int NOT NULL AUTO_INCREMENT
Related
Let's imagine a table below, where;
ID is the primary key and it is auto incremental column
ItemType is a foreign key
OrderID is the order number for each ItemType value
ID ItemType OrderID Col1
== ======== ======= ====
1 1 1 ABCD
2 1 2 XYZT
3 2 1 BDKL
4 1 3 XXXX
5 1 4 TYTY
6 2 2 ABCD
7 1 5 XYZZ
8 3 1 ABCD
9 3 2 ABCD
10 1 6 XYZT
11 2 3 ABCD
as you see there might be more than one ItemType that comes from another table, and each ItemType has a sequential OrderID that starts from 1 and increases by 1 for every record.
My Question is;
what is the best practice to have a column that keeps the OrderID information correctly?
Assuming that the ID values would always be increasing, such that a subsequent order's ID value would always be greater than an an earlier order's ID value, we could just use ROW_NUMBER here and not even use a column:
SELECT
ID,
ItemType,
ROW_NUMBER() OVER (PARTITION BY ItemType ORDER BY ID) OrderID,
Col1
FROM yourTable
ORDER BY
ID;
Demo
If my assumption of the ID column might not be correct always, then I suggest adding a new timestamp column which records when each order actually happened. Then, use something similar to the above approach, but order based on the order timestamp.
You do not need to do this - it will be difficult to implement and you can face some performance issues if batches of orders are created at the same time. As there is no built -in group by identity or identity over (partition by) you need to get the maximum value for each inserted type - and this should be in transaction and will be blocking others inserted.
So, just have a normal identity column to guarantee uniqueness of each order and use ROW_NUMBER to get the OrderID in incremented way by type in the presentation lair.
I have a table that looks like this:
ID A B Count
-----------------
1 abc 0 1
2 abc 0 2
3 abc 1 1
4 xyz 1 1
5 xyz 1 2
6 xyz 1 3
7 abc 1 2
8 abc 0 3
The "Count" column is incremented by one in the next insertion depending on the value of fields "A" and "B". so for example, if the next record I want to insert is:
ID A B Count
-----------------
abc 0
The value of count will be 4.
I have been trying to find documentation about this, but I'm still quite lost in the MS SQL world! There must be a way to configure the "Count" column as a sequence dependent on the other two columns. My alternative would be to select all the records with A=abc and B=0, get the maximum "Count", and do +1 in the latest one, but I suspect there must be another way related to properly defining the Count column when creating the table.
The first question is: Why do you need this?
There is ROW_NUMBER() which will - provided the correct PARTITION BY in the OVER() clause - do this for you:
DECLARE #tbl TABLE(ID INT,A VARCHAR(10),B INT);
INSERT INTO #tbl VALUES
(1,'abc',0)
,(2,'abc',0)
,(3,'abc',1)
,(4,'xyz',1)
,(5,'xyz',1)
,(6,'xyz',1)
,(7,'abc',1)
,(8,'abc',0);
SELECT *
,ROW_NUMBER() OVER(PARTITION BY A,B ORDER BY ID)
FROM #tbl
ORDER BY ID;
The problem is: What happens if a row is changed or deleted?
If you write this values into a persistant column and one row is removed physically, you'll have a gap. Okay, one can live with this... But if a value in A is changed from abc to xyz (same applies to B of course) the whole approach breaks.
If you still want to write this into a column you can use the ROW_NUMBER() from above to fill these values initially and a TRIGGER to set the next value with your SELECT MAX()+1 approach for new rows.
If the set of combinations is limited you might create a SEQUENCE (needs v2012+) for each.
But - to be honest - the whole issue smells a bit.
I have a table with two columns, where none of the columns is unique. I need to auto increment the column number separately for each user.
user | number
1 | 1
2 | 1
1 | 2
3 | 1
The only idea I could come up with is to search for the last number used and manually increment by one. Is there a more efficient way?
Instead of the number field, You can create an auto increment field in the table (I call it id), and get the desired number via a query:
first adding id:
alter table table_name add id int not null IDENTITY(1,1)
you do not need the number field anymore:
alter table table_name drop column number
The query to get number (you can use it to create a view):
select user,
row_number() over(partition by user order by id) as number
from table_name
Search for a user maximum and increment it.
INSERT INTO YOUR_TABLE (user, number)
SELECT (MAX(number) + 1)
FROM YOUR_TABLE
WHERE user = USER_ID
The term of auto-increment covers only the primary key auto-increment. See this page, for more information.
You can do it like in two query:
userno - id of user in integer you want to insert
first write(query 1) i.e if userno already there in table:
insert into table_name
select userno,count(*) from table_name where user = userno
group by user;
if it returns empty row then simply write(query 2) i.e it is a new user to be inserted:
insert into table_name values(userno,1);
Inserting one table's complete column data to a particular column in another table in SQL SERVER
I have two tables i.e AuditCalendar, ScheduleAudit
Audit Calendar has two columns Taskid, TaskTypeId
Schedule Audit has two columns Scheduleid, Taskid
Audit Calendar looks like this
Taskid (Auto increment) TaskTypeId
-------------------------------------
1 1
2 2
3 3
4 1
5 1
But I want Taskid column data from Audit Calendar table based on TaskTypeId .Columns
After completion of query, the ScheduleAudit table should look like this
Scheuleid (AutoIncrement) Taskid
-------------------------------------
1 1
2 1
3 1
I have to run this query seems to look like a error
Subquery returns more than one value
Query is:
INSERT INTO ScheduleAudit(TaskId)
VALUES ((SELECT TaskId FROM AuditCalendar Where TaskTypeId = 1))
Please can you suggest how I can do this approach I am new to SQL Server but someone says that use cursors.... I am really confused last 1 week on words. And also search google but not get it now...Please can you give me any one valuable suggestions.
insert ... values is supposed to insert a single row. So what you have in the parentheses is supposed to produce a single row, or else it would fail.
There's no need to use insert ... values, when you can use insert ... select:
INSERT INTO ScheduleAudit(TaskId)
SELECT TaskId FROM AuditCalendar Where TaskTypeId=1
...however, that would produce
1 1
2 4
3 5
I'm not sure I understand the logic behind producing your example output.
How can I show the number of rows in a table in a way that when a new record is added the number representing the row goes higher and when a record is deleted the number gets updated accordingly?
To be more clear,suppose I have a simple table like this :
ID int (primary key) Name varchar(5)
The ID is set to get incremented by itself (using identity specification) so it can't represent the number of row(record) since if I have for example 3 records as:
ID NAME
1 Alex
2 Scott
3 Sara
and I delete Alex and Scott and add a new record it will be:
3 Sara
4 Mina
So basically I'm looking for a sql-side solution for doing this so that I don't change anything else in the source code in multiple places.
I tried to write something to get the job done but it failes. Here it is :
SELECT COUNT(*) AS [row number],Name
FROM dbo.Test
GROUP BY ID, Name
HAVING (ID = ID)
This shows as:
row number Name
1 Alex
1 Scott
1 Sara
while I want it to get shown as:
row number Name
1 Alex
2 Scott
3 Sara
If you just want the number against the rows while selecting the data and not in the database then you can use this
select row_number() over(order by id) from dbo.Test
This will give the row number n for nth row.
Try
SELECT id, name, ROW_NUMBER() OVER (ORDER BY id) AS RowNumber
FROM MyTable
What you want is called an auto increment.
For SQL-Server this is achieved by adding the IDENTITY(1,1) attribute to the table definition.
Other RDBMS use a different syntax. Firebird for example has generators, which do the counting. In a BEFORE-INSERT trigger you would assign the ID-field to the current value of the generator (which will be increased automatically).
I had this exact problem a while ago, but I was using SQL Server 2000, so although row number() is the best solution, in SQL Server 2000, this isn't available. A workaround for this is to create a temporary table, insert all the values with auto increment, and replace the current table with the new table in T-SQL.