SQL Update same field using a different ID - sql

How can one update the same field's value using a different ID?
Customer ORderType
Matt 1
Jake 2
For all "Matt"s I want to set the orderType to 2 from Jake.
This doesnt work.
declare #X nvarchar (250)
set #x = (select OrderType from table where Customer = 'Matt')
update table
set OrderType = #x
where Customer = 'Jake'

You can include a FROM clause in an UPDATE query.
UPDATE C SET OrderType = J.OrderType
FROM [Table] C
CROSS JOIN [Table] J
WHERE C.Customer = 'Matt' AND J.Customer = 'Jake'
If you use a subquery instead, that subquery must return precisely one row.
Note also that your quoted line:
set #x = (select OrderType from table where Customer = 'Matt')
Can also be written as:
SELECT #x = OrderType FROM Table WHERE Customer = 'Matt'
People tend to overuse subqueries.

update table
set OrderType = (select top 1 OrderType from table where Customer = 'Matt')
where Customer = 'Jake'

update table
set OrderType = (select TOP 1 OrderType from table where Customer = 'Matt')
where Customer = 'Jake'

Related

using IF ELSE in sql server (what to put in the IF statement)

I am using the IF statement to insert data into ProductTable(using this name as an example) so how do i open the IF statement... the below calls the IF query but never reaches the else, which would be if it does exist in the table so here is an example of where I am at the moment. my error lies within the IF statement at the start but I cant work out what to put in to make it work
IF NOT EXISTS(SELECT TOP 1 ProductID FROM ProductTable)
BEGIN
INSERT
(ProductName, UnitPrice)
SELECT
ProductView.ProductName,
ProductView.UnitPrice
FROM ProductView
INNER JOIN ProductTable ON ProductView.ProductID = ProductTable. ProductID
WHERE ProductID = (SELECT TOP 1 ProductID FROM ProductTable ORDER BY changedate DESC)
AND NOT EXISTS(SELECT 1 FROM ProductTable WHERE ProductView.ProductID = ProductTable.ProductID)
END
ELSE
INSERT
(ProductName, UnitPrice)
SELECT
ProductView.ProductName,
UnitPrice = 0.00
FROM ProductView
INNER JOIN ProductTable ON ProductView.ProductID = ProductTable. ProductID
WHERE ProductID = (SELECT TOP 1 ProductID FROM ProductTable ORDER BY changedate DESC)
How about
SELECT TOP 1 1 FROM Table1
IF ##ROWCOUNT = 0
BEGIN
-- Do stuff
END
this is what I was after:
IF NOT EXISTS(SELECT ProductTable.CustomerReference FROM ProductTable)
BEGIN
something
END
ELSE
something else
I didn't need to include the TOP 1 and also I was missing a relationship which referenced it to the main table

Selective update in SQL Server

I've created a junction table like this one:
http://imageshack.us/scaled/landing/822/kantotype.png
I was trying to figure out a query that could able to select some rows - based on the PokémonID - and then updating only the first or second row after the major "filtering".
For example:
Let's suppose that I would like to change the value of the TypeID from the second row containing PokémonID = 2. I cannot simply use UPDATE KantoType SET TypeID = x WHERE PokémonID = 2, because it will change both rows!
I've already tried to use subqueries containing IN,EXISTS and LIMIT, but with no success.
Its unclear what are your trying to do. However, you can UPDATE with JOIN like so:
UPDATE
SET k1.TypeID = 'somethng' -- or some value from k2
FROM KantoType k1
INNER JOIN
(
Some filtering and selecting
) k2 ON k1.PokémonID = k2.PokémonID
WHERE k1.PokémonID = 2;
Or: if you want to UPDATE only the two rows that have PokémonID = 2 you can do this:
WITH CTE
AS
(
SELECT *,
ROW_NUMBER() OVER(ORDER BY TypeID) rownum
FROM KantoType
WHERE PokemonID = 2
)
UPDATE c
SET c.TypeID = 5
FROM CTE c
WHERE c.rownum = 1;
SQL Fiddle Demo
I can suggest something like this if you just need to update a single line in your table:
UPDATE kantotype
SET
type = 2
WHERE pokemon = 2
AND NOT EXISTS (SELECT * FROM kantotype k2
WHERE kantotype.type > k2.type
AND kantotype.pokemon = k2.pokemon)
It would be easier to get the first or last item of the table if you had unique identifier field in your table.
Not sure even if you are trying to update the row with PokemenID =2 by doing a major filtering on TypeID... So just out of assumptiong (big one), you can give a try on Case
UPDATE yourtable a
LEFT JOIN youtable b on a.pokeid = b.pokeid
SET a.typeid = (CASE
WHEN a.typeid < b.typeid THEN yourupdatevalue
WHEN a.typeid > b.typeid THEN someothervalue
ELSE a.typeid END);
If you know the pokemon ID and the type id then just add both to the where clause of your query.
UPDATE KantoType
SET TypeID = x
WHERE PokémonID = 2
AND TypeID=1
If you don't know the type ID, then you need to provide more information about what you're trying to accomplish. It's not clear why you don't have this information.
Perhaps think about what is the unique identifier in your data set.

Error using Update Join statement from a Table Variable

If I make a table variable here:
declare #Table Table (ProductID int, Color = varchar(60))
Then populate it of course, and try to use it in an Update with Join statement like below, I get errors.
UPDATE [Product]
SET [Product].[Active] = 1
,[Product].[Color] = t.[Color]
INNER JOIN #Table t
ON t.[ProductID] = [Product].[ProductID]
Error:
Msg 156, Level 15, State 1, Procedure
Incorrect syntax near the keyword 'INNER'.
Any suggestions how to do this?
You can also do this (works on SQL Server and all ANSI SQL conforming database):
UPDATE [Product] SET
[Product].[Active] = 1
,[Product].[Color] = t.[Color]
FROM #Table t
WHERE t.[ProductID] = [Product].[ProductID]
There's something to be desired from SQL Server's proprietary UPDATE FROM though, you can easily change the UPDATE statement to make it match whole table regardless if there's no matching rows.
It's easy to fashion this matched-rows-only update... http://www.sqlfiddle.com/#!3/8b5a3/26
update p SET
Qty = t.Qty
from Product p
inner join Latest t
on t.ProductId = p.ProductId;
...to an UPDATE that matches all rows, you merely change the INNER JOIN to LEFT JOIN: http://www.sqlfiddle.com/#!3/8b5a3/27
update p SET
Qty = ISNULL(t.Qty,0)
from Product p
left join Latest t
on t.ProductId = p.ProductId;
select * from Product;
Whereas if you want to fashion the ANSI SQL UPDATE with matched-rows-only ... http://www.sqlfiddle.com/#!3/8b5a3/28
update Product SET
Qty = t.Qty
from Latest t
where t.ProductId = Product.ProductId
...to UPDATE statement that matches all rows, you have to adjust your query a bit: http://www.sqlfiddle.com/#!3/8b5a3/29
update Product SET
Qty = ISNULL(t.Qty, 0)
from
(
select x.ProductId, lat.Qty
from Product x
left join Latest lat on lat.ProductId = x.ProductId
) as t
where t.ProductId = Product.ProductId;
Though as most choices in development, one should weigh the pros and cons in terms of code readability/maintainability against flexibility
Data sample:
create table Product
(
ProductId int primary key not null,
Name varchar(50) not null,
Qty int not null
);
insert into Product(Name,Qty) values
(1,'CAR',1),
(2,'Computer',1000),
(3,'Shoes',2);
create table Latest
(
ProductId int primary key not null,
Qty int not null
);
insert into Latest(ProductId, Qty) values
(2,2000),
(3,3);

Update in child table, only one value got updated

Below I am trying to update value of a parent table from child table and counting matching values. Tables in my db:
issue_dimension with id = issue_id and have column accno.
star_schema with id star_id,this Child column have fk issue_id and column book_frequency
The book_frequency need to match the count of each accno in parent table , I tried this
update [test1] .[dbo] .star_schema
set [book_frequency] = (
select top 1 COUNT([issue_dimension].ACCNO)as book_frequency
from issue_dimension
group by ACCNO having (COUNT(*)>1) and
issue_dimension.ACCNO = star_schema .ACCNO
)
It only updates only 1st value count issue_dimension. I need to count every accno in issue_dimension and update it to matching accno of star_schema.
I never did update by joining two or more tables , can anyone help in this with joins
UPDATE s
SET [book_frequency] = i.CNT
FROM [test1].[dbo].star_schema s
INNER JOIN
(
SELECT ACCNO, COUNT(*) as CNT
FROM issue_dimension
GROUP BY ACC_NO
HAVING COUNT(*)>1
) i on (s.ACCNO = i.ACCNO)
I didn't check it but it should works
Try in this way, without grouping, just with the WHERE clause:
UPDATE [test1].[dbo].star_schema SET
[book_frequency] =
(
SELECT COUNT([issue_dimension].ACCNO)
FROM issue_dimension
WHERE issue_dimension .ACCNO = star_schema.ACCNO
HAVING COUNT(*)>1
)
It's not fully clear to me so the answer is a bit of guessing:
update s set
book_frequency = t.qty
from star_schema s
join issue_dimension i on s.issue_id = s.issue_id
join (select count(*) as qty, accno
from issue_dimension
group by accno
) t on i.accno = t.accno
Here's the example from BOL that does the kind of thing you're looking for, using AW:
USE AdventureWorks2008R2;
GO
UPDATE Sales.SalesPerson
SET SalesYTD = SalesYTD +
(SELECT SUM(so.SubTotal)
FROM Sales.SalesOrderHeader AS so
WHERE so.OrderDate = (SELECT MAX(OrderDate)
FROM Sales.SalesOrderHeader AS so2
WHERE so2.SalesPersonID = so.SalesPersonID)
AND Sales.SalesPerson.BusinessEntityID = so.SalesPersonID
GROUP BY so.SalesPersonID);

SQL: Is there any way to use Order By on an update statement?

I need to update one record only in a database, and assign it to a user. Here is what I am doing:
UPDATE TOP (1) books SET assigneduser = 1
WHERE bookstatus = 7
AND ((assigneduser is null) or (assigneduser = 1));
I also have a field named bookname which I would prefer to order by, but update does not seem to support it.
Also note that I will have 50 users using the software at once, so I will need to ensure that only one user is assigned a book. Otherwise I would run a select first and then an update on the top record.
Thanks.
You have to first select the desired record, then update it:
update books
set assigneduser = 1
where BookPrimaryKeyField = (
SELETE TOP 1 BookPrimaryKeyField
from books
WHERE bookstatus = 7
AND ((assigneduser is null) or (assigneduser = 1));
)
If you want to update only one row in the database the best way to do it is to find out what is its primary key and use it. You can do that by saying
UPDATE books SET assigneduser = 1
WHERE BOOKID
= (SELECT top 1 BOOKID FROM books where
bookstatus = 7
AND ((assigneduser is null) or (assigneduser = 1)));
UPDATE B
SET assigneduser = 1
FROM books B
WHERE bookstatus = 7
AND ((assigneduser is null) or (assigneduser = 1))
and bookid = (select min(bookid) from books where assigneuser is null)
I assumed you had an ID column bookid.
This gets you the lowest book id with no user assigned, and joins it back to books to give you a single record (as part of b) which you can then update.
Look at http://msdn.microsoft.com/en-us/library/ms177523.aspx.
If you must use TOP to apply updates in a meaningful chronology, you must use TOP together with ORDER BY in a subselect statement. The following example updates the vacation hours of the 10 employees with the earliest hire dates.
UPDATE HumanResources.Employee
SET VacationHours = VacationHours + 8
FROM (SELECT TOP 10 BusinessEntityID FROM HumanResources.Employee
ORDER BY HireDate ASC) AS th
WHERE HumanResources.Employee.BusinessEntityID = th.BusinessEntityID;
GO
It would probably be easier to break this into 2 pieces
DECLARE #bookid as INT
SELECT TOP (1) #bookid = id FROM books
WHERE bookstatus = 7
AND ((assigneduser is null) or (assigneduser = 1))
ORDER BY bookname
UPDATE books SET assigneduser = 1
WHERE id = #bookid
There is a way to get around it by using a subquery as following:
UPDATE books SET assigneduser=1
AND ((assigneduser is null) or (assigneduser = 1))
AND bookname in (SELECT TOP 1 bookname FROM Table ORDER BY bookname DESC)
Since update doesn't return any data and 'order by' sorts a result set, there is nothing for ORDER BY to work on, and what you seek cannot be done.
If you want to assign only one book you could update using a join on top 1 from you set.
UPDATE b0 SET assigneduser = 1
FROM b0
INNER JOIN
(SELECT top 1 id FROM books
WHERE user = 1 OR user is null
AND status =7) b1 ON b1.id = b0.id
or perhaps less cryptic
UPDATE user SET assigneduser = 1
WHERE id IN
(SELECT top 1 id FROM books
WHERE user = 1 OR user is null
AND status =7) b1 ON b1.id = b0.id
Whether that strategy is robust regarding concurrency is a matter of transaction semantics.