I have a Table Valued Function qlikview_verlauf. I want to return a table with id, Date and Path.
Identity(seed, increment)
The ID is an autoincrement value. I want to start this autoincrement (seed) from the max(id)+1 from another table named Testfortschritt.
I have tried the following, but it doesn't work. The Error Message is incorrect Syntax.
Create FUNCTION [dbo].[qlikview_verlauf](#param INT)
RETURNS #qlikview_verlauf table (
ID INT IDENTITY((Select max(id) from Testfortschritt),1)
,[Date] date NOT NULL
,[Path] varchar(600) NOT NULL
)
I would set aside the IDENTITY of your ID column and rather use ROW_NUMBER to generate the ID in your SELECT statement.
For example:
SELECT
(SELECT MAX(id) FROM Testfortschritt) +
ROW_NUMBER OVER(ORDER BY (SELECT 1)) AS ID,
[Date],
[Path]
FROM <YourTable>
Since I don't know how your exact statement looks like, I used ORDER BY (SELECT 1) which lets SQL Server decide in which order records are numbered. If you have a specific order just replace (SELECT 1) with your order columns.
Since the ID should be uniqe I also omitted the PARTITION BY clause which isn't needed in your scenario.
More about ROW_NUMBER can be found here
Related
There is a table with tow columns(ID, Data) and there are 3 rows with same value.
ID Data
4 192.168.0.22
4 192.168.0.22
4 192.168.0.22
Now I want to change third row DATA column. In update SQL Server Generate an error that I ca not change the value.
I can delete all 3 rows. But I can not delete third row separately.
This table is for a software that I bought and I changed the third Server IP.
You can try the following query
create table #tblSimilarValues(id int, ipaddress varchar(20))
insert into #tblSimilarValues values (4, '192.168.0.22'),
(4, '192.168.0.22'),(4, '192.168.0.22')
Use Below query if you want to change all rows
with oldData as (
select *,
count(*) over (partition by id, ipaddress) as cnt
from #tblSimilarValues
)
update oldData
set ipaddress = '192.168.0.22_1'
where cnt > 1;
select * from #tblSimilarValues
Use Below query if you want to skip firs row
;with oldData as (
select *,
ROW_NUMBER () over (partition by id, ipaddress order by id, ipaddress) as cnt
from #tblSimilarValues
)
update oldData
set ipaddress = '192.168.0.22_2'
where cnt > 1;
select * from #tblSimilarValues
drop table #tblSimilarValues
You can find the live demo live demo here
Since there is no column that allows us to distinguish these rows from each other, there's no "third row" (nor a first or second one for that matter).
We can use a ROW_NUMBER function to apply arbitrary row numbers to these rows, however, and if we place that in a CTE, we can apply DELETE/UPDATE actions via the CTE and use the arbitrary row numbers:
declare #t table (ID int not null, Data varchar(15))
insert into #t(ID,Data) values
(4,'192.168.0.22'),
(4,'192.168.0.22'),
(4,'192.168.0.22')
;With ArbitraryAssignments as (
select *,ROW_NUMBER() OVER (PARTITION BY ID, Data ORDER BY Data) as rn
from #t
)
delete from ArbitraryAssignments where rn > 2
select * from #t
This produces two rows of output - one row was deleted.
Note that I say that the ROW_NUMBER is arbitrary. One of the expressions in both the PARTITION BY and ORDER BY clauses is the same. By definition, then, we know that no real ORDER is defined by this (because all rows within the same partition, by definition, have the same value for that expression).
In this case ID columns allows duplicate value which is wrong, ID should be unique.
Now what you can do is create a new column make that unique or Primary Key or change the duplicate values of ID column and make it Unique/Primary key.
Now as per your Unique key/Primary key you can update DATA column value by query as below:
UPDATE <Table Name>
SET DATA = 'new data'
WHERE ID = 3;
I have a statement in stored procedure
INSERT into table(ID, name, age)
SELECT fnGetLowestFreeID(), name, age
FROM #tempdata
The function fnGetLowestFreeID() gets the lowest free ID of the table table.
I want to insert unique ID with every record in the table. I have tried iteration and transaction. But they aren't fitting the scenario.
I cannot use Identity Column. I have this restriction of using IDs between 0-4 and assigning the lowest free ID using that function. In case of returned ID greater than 4, the function is returning an error. Suppose there are already 1 and 2 in the table. The function will return 0 and I have to assign this ID to the new record, 3 to the next record and so on on the basis of number of records in the #tempdata.
try this
CREATE TABLE dbo.Tmp_City(Id int NOT NULL IDENTITY(1, 1),
Name varchar(50) , Country varchar(50), )
OR
ALTER TABLE dbo.Tmp_City
MODIFY COLUMN Id int NOT NULL IDENTITY(1, 1)
OR
Create a Sequence and assign Sequence.NEXTVAL as ID
in the insert statement
You can make use of a rank function like row_number and do something like this.
INSERT into table(ID, name, age)
SELECT row_number() over (order by id) + fnGetLowestFreeID(), name, age
FROM #tempdata
Here are 3 scenarios-
1)Show the function which you are using
2) Doesn't make sense to use a function and make it unique
still- you can use rank-
INSERT into table(ID, name, age)
SELECT row_number() over (order by id) + fnGetLowestFreeID(), name, age
FROM #tempdata
3)Else, get rid of function and use max(id)+1 because you dont want to use identitiy column
You could use a Numbers table to join the query doing your insert. You can google the concept for more info, but essentially you create a table (for example with the name "Numbers") with a single column "nums" of some integer type, and then you add some amount of rows, starting with 0 or 1, and going as far as you need. For example, you could end with this table content:
nums
----
0
1
2
3
4
5
6
Then you can use such a table to modify your insert, you don't need the function anymore:
INSERT into table(ID, name, age)
SELECT t2.nums, t.name, t.age
FROM (
SELECT name, age, row_number() over (order by name) as seq
FROM #tempdata
) t
INNER JOIN (
SELECT n.nums, row_number() over (order by n.nums) as seq
FROM Numbers n
WHERE n.nums < 5 AND NOT EXISTS (
SELECT * FROM table WHERE table.ID = n.nums
)
) t2 ON t.seq = t2.seq
Now, this query leaves out one of your requirements, that would be launching an error when no slots are available, but that is easy to fix. You can do previously a query and test if the count of records in table plus the sum of records in #tempdata is higher than 5. If so, you launch the error as you know there would not be enough free slots for the records in #tempdata.
Side note: table looks like a terrible name for a table, I hope that in your real code you have a meaningful name :)
I'm trying to add a new column to an existing table, where the value is the row number/rank. I need a way to generate the row number/rank value, and I also need to limit the rows affected--in this case, the presence of a substring within a string.
Right now I have:
UPDATE table
SET row_id=ROW_NUMBER() OVER (ORDER BY col1 desc) FROM table
WHERE CHARINDEX('2009',col2) > 0
And I get this error:
Windowed functions can only appear in the SELECT or ORDER BY clauses.
(Same error for RANK())
Is there any way to create/update a column with the ROW_NUMBER() function? FYI, this is meant to replace an incorrect, already-existing "rank" column.
You can do this with a CTE, something like:
with cte as
(
select *
, new_row_id=ROW_NUMBER() OVER (ORDER BY col1 desc)
from MyTable
where charindex('2009',col2) > 0
)
update cte
set row_id = new_row_id
SQL Fiddle with demo.
If you are only updating a few thousand rows, you could try something like this:
select 'UPDATE MyTable SET ID = ' + CAST(RowID as varchar) + ' WHERE ID = ' + CAST(ID as varchar)
From (
select MyTable, ROW_NUMBER() OVER (ORDER BY SortColumn) RowID from RaceEntry
where SomeClause and SomeOtherClause
) tbl
Copy and paste the query results into the query editor and run. It's a bit sluggish and yukky bit it works.
Simple workaround would be to create a temp table that looks like
CREATE TABLE #temp (id int, rank int)
Where id is the same type as primary key in you main table.
Just use SELECT INTO to first fill temp table and then update from temp tableā¦
Using SQL Server 2005
Table1
Code ID (identity field)
001 1
001 2
002 1
003 1
003 2
How to create a identity field based on the code.
Need Query Help
Just like this:
ALTER TABLE dbo.YourTable
ADD NewColumn INT IDENTITY(1,1)
You can define the seed (starting value) as the first parameter, and the step (increments) as the second - so pick whatever makes sense to you; both seed=1 and step=1 seems to be the mostly used defaults.
The column will be added and populated with values when it's creatde.
It looks like you want to implement row_number() which will increment the id value based on the number of code values that you have:
select code, id
from
(
select code,
row_number() over(partition by code order by code) id
from yourtable
) d;
Using row_number() will allow you to calculate the value when you query the data in your table. See SQL Fiddle with Demo.
If you want to update your table with this value, then you could use something like the following:
;with cte as
(
select code, id,
row_number() over(partition by code order by code) rn
from yourtable
)
update cte
set id = rn;
See Demo.
Storing this value in your table will be difficult to maintain if you continue to add new rows for each code, it might be easier to implement the row_number() when you query the data.
Use ROW_NUMBER
SELECT
code,
ROW_NUMBER() OVER(PARTITION BY code ORDER BY code) AS ID
FROM Table1
(On rereading your question, I see that your id column is not unique, so it could not be an identity column.)
To create an identity field that uses initial values from the Code column, you could:
-- Create an empty copy of your table
select top 0 *
into CopiedTable
from YourTable;
-- Add an identity column
alter table CopiedTable add id int identity;
-- Copy the rows over, while initializing the identity column from Code
set identity_insert dbo.CopiedTable on
insert dbo.CopiedTable
(id, Code)
select Code
, Code
from dbo.YourTable;
set identity_insert dbo.CopiedTable off
-- Drop the old table
drop table dbo.YourTable
-- Rename the copied table
exec sp_rename 'CopiedTable', 'YourTable'
get it from count
DECLARE #ID int = (
SELECT COUNT(*) + 1 from test_1 WHERE [Code] = #CODE )
How would I dynamically number rows in a query similar to this:
Select distinct name from #table where %rules
When I add ROW_NUMBER() OVER() I lose my distinct property, and it returns every element in table, with a unique row number.
Select distinct ROW_NUMBER OVER(order by name), name from #table where %rules
I don't want to create a temporary table, otherwise I would make a primary key for the temporary table and have it insert row numbers that way.
Thanks in advance!
Use like this.
select ROW_NUMBER() OVER(order by name), * from
(Select distinct name from #table where %rules) as mytable