Update random row according to condition - sql-server-2012

I have a database with rows where a column is null. I want to update random rows with a new value on this column however I'm having trouble writing the SQL for this.
UPDATE TOP 1 [dbo].Invoice SET
document_id = #guid
WHERE document_id IS NULL
ORDER BY NEWID()
What I want to do here is update the document_id with a new guid on 1 random row. (the actual guid is not seen above)

You could try using a CTE here:
WITH cte AS (
SELECT TOP 1 document_id
FROM [dbo].Invoice
WHERE document_id IS NULL
ORDER BY NEWID()
)
UPDATE cte
SET document_id = #guid;

Related

Update query where set statement gets value from another table

SQL Server 2008 R2
Table CIRTB
CIRLogID PrimaryKey
StaffName
StaffID
Table StaffTB
StaffID - PrimaryKey
Fullname
DOB
CIN
Program
I have StaffID's in the CIRTB table that are Null, so I need to update it from the Staff table.
I know I need something like the following
update CIRTB
set CIRTB>staffid = (select staffid
from stafftb
where stafftb.fullname = cirtb.Staffname)
where CIRTB.staffid is null
One problem that I am stuck on: there are some duplicates in the StaffTB for fullname, dob, program
One way to do the UPDATE is using a CTE:
;WITH ToUpdate AS (
SELECT t1.StaffID AS t1_StaffID, t2.StaffID AS t2_StaffID,
ROW_NUMBER() OVER (PARTITION BY t2.Fullname
ORDER BY t2.DOB DESC) AS rn
FROM CIRTB AS t1
JOIN StaffTB AS t2 ON t1.StaffName = t2.Fullname
WHERE t1.StaffID IS NULL
)
UPDATE ToUpdate
SET t1_StaffID = t2_StaffID
WHERE rn = 1
The CTE uses ROW_NUMBER in order to pick one record per Fullname. The ORDER BY clause of the window function determines which record is picked in case of duplicates: since DOB DESC is used, the record having the most recent DOB is selected.
Use TOP 1 in the sub-select to make sure it only returns one row even if there are duplicates.

LIMIT equivalent for SQL Server 2012 in an UPDATE statement

I have the following table below and am trying to update the first available row with an user ID through a query, but I need to limit this to only update one row and not multiple.
ID Model UserID
1 X12T5 1
2 X13T5 2
3 X14T5 NULL
4 X15T5 NULL
The first available row would be where ID is 3. I would update it with the following query:
UPDATE Table SET UserID = '3' WHERE UserID IS NULL
But I want to make sure it affects only 1 row and not multiple that are available, LIMIT doesn't exist in SQL Server.
What would the best way to achieve this?
You can do this with UPDATE TOP. It's the equivalent of a SELECT TOP but for updates; and TOP is SQL Server's equivalent of MySQL's LIMIT.
See further info.
UPDATE Table SET UserID = '3'
WHERE UserID IS NULL
AND Id IN (SELECT top 1 ID FROM table where UserId IS NULL)
You can also use any of the following methods (Assuming column ID is of integer datatype)
Using subquery :
UPDATE a
SET a.UserID='3'
FROM YourTable a
WHERE ID =( SELECT MIN(ID)
FROM YourTable
WHERE UserID is NULL)
Using JOIN:
UPDATE a
SET a.UserID='3'
FROM YourTable a
JOIN
( SELECT MIN(ID) MinId
FROM YourTable
WHERE UserID is NULL) b
ON a.ID=b.MinId
Using CTE
WITH cte_a
AS
(SELECT MIN(ID) MinId
FROM YourTable
WHERE UserID is NULL)
UPDATE a
SET a.UserID='3'
FROM YourTable a
JOIN cte_a b a.ID=b.MinId
You can also use CTE & perform the SELECT\UPDATE\DELETE operations ,
; WITH CTE AS (
SELECT TOP 10 * FROM TABLE
)
UPDATE CTE
SET ...
DELETE\UPDATE\SELECT works with CTE ... Cool !!!

Syntax for INSERT INTO SELECT statement

I have a table with an Identity column (ArticleID). I would like to select the last row in the table and insert a value into a particular column (ArticleImage). I already have the value, so I needn't query for it. Where in the SQL statement do I place this value?
INSERT INTO EasyDNNNews (ArticleImage)
SELECT TOP 1 FROM EasyDNNNews
ORDER BY ArticleID DESC
You can do this with a subquery or updatable CTE:
WITH toupdate as (
SELECT TOP 1 d.*
FROM EasyDNNNews d
ORDER BY ArticleID DESC
)
UPDATE toupdate
SET ArticleImage = ??;
Like commentator's have hinted, you need an UPDATE statement, not an INSERT. UPDATE, updates a record that already exists, where INSERT creates a whole brand spanking new record.
Yours is a little more complicated than just a UPDATE <table> SET <field>='Somevalue'; since you want to update a specific record based on a sort. You were headed in the right direction with your SELECT TOP 1.. query.
UPDATE EasyDNNNews
SET ArticleImage = 'YOURVALUE'
WHERE ArticleID = (SELECT TOP 1 ArticleID FROM EasyDNNNews ORDER BY ArticleID Desc)`
That subquery fetches the max ArticleID. The outer UPDATE statement then updates that Articleid's record, setting ArticleImage to whatever value you want to stick in there.

Limit row a table in SQL and Insert new rows on Top

I have a SQL Server database table : History_KH
It look like:
Now I want to limit row number of this table (ex : 200 rows)
And when I insert new rows from code, It will insert on top of table. That's mean : Insert new rows on top of database table and the old rows over of 200 counts will be delete.
Please support me.
You can't really limit a table for a fix number of records but you can get rid of unwanted records. Assuming you are on SQL-Server
--STEP1 :Do your insert here
--STEP2: Delete older records over 200 ordering by dateTime column
;WITH CTE AS (
SELECT *, ROW_NUMBER() OVER (ORDER BY DateTime DESC) rn
FROM YourTable
)
DELETE CTE WHERE rn > 200
You didn't even post what database you are using. I'm assuming mysql.
Assuming you want to order by Datetime and Username is unique, use this update...
update `History_KH` set `Username` = $myUser, `Datetime` = $myDatetime,
`Datechange` = $myDatechange, `Value` = $myValue where `Username` in
(select `Username` from `History_KH` order by `Datetime` limit 200)

Delete oldest records from database

I have a database with 1000 records.
I am trying to create an SQL statement so if the number of records grows above 1000, then the oldest records are deleted (i.e. the new records above 1000 'replace' the oldest records).
I am using SQLite, but I assume the usual SQL syntax will fit here.
If you use an auto-increment field, you can easily write this to delete the oldest 100 records:
DELETE FROM mytable WHERE id IN (SELECT id FROM mytable ORDER BY id ASC LIMIT 100)
Or, if no such field is present, use ROWID:
DELETE FROM mytable WHERE ROWID IN (SELECT ROWID FROM mytable ORDER BY ROWID ASC LIMIT 100)
Or, to leave only the latest 1000 records:
DELETE FROM mytable WHERE ROWID IN (SELECT ROWID FROM mytable ORDER BY ROWID DESC LIMIT -1 OFFSET 1000)
Assuming that your table has a Primary Key and a column with a timestamp indicating when the record was inserted), you can use a query along the lines of
delete from tableToDeleteFrom
where tablePK in
(select tablePK
from tableToDeleteFrom
where someThresholdDate <= #someThresholdDate)
For delete all records except the first record (min/max id) you can use:
SET #ls AS INT
SELECT #ls = MIN(id) FROM DATA
DELETE FROM DATA WHERE id <> #ls