Update query for a specfic columns in all rows - sql

I'm searching for check a columns value in all the rows and update with a where clause as a condition. My case is as follows:
SubscriptionID ChannelURI StudentID
1 XXXX 4
2 yyyy 4
3 XXXX 3
4 XXXX 4
5 XXXX 2
I want to check the column channel uri value for a specfic student and for all matched results to set it to null.
So in this case row 3 and 5 should be set to null.
I've tried this, but it set all channeluri of other rows than studnetid = 4 to null
UPDATE SubscriptionCourse
Set ChannelURI = 1
, DeviceId = null
FROM SubscriptionCourse as t1
INNER JOIN SubscriptionCourse as t2
on t1.ChannelURI = t2.ChannelURI
WHERE StudentId! = 4

Reference the table to be updated by it's alias given in the FROM clause, rather than by name (since the same table name is referenced twice. Also qualify the reference on StudentId in the WHERE clause with the table alias as well.
UPDATE t1
SET t1.ChannelURI = 1
, t1.DeviceId = NULL
FROM SubscriptionCourse t1
JOIN SubscriptionCourse t2
ON t1.ChannelURI = t2.ChannelURI
WHERE t1.StudentId != 4
You say you want to set ChannelURI to NULL, but your statement is setting to a literal value of 1. I've left the assignment as you specified in your statement, but qualified the columns with the table alias.
I don't think this is your problem, but I never include a space in the "not equals" comparison operator symbol (!=). I've just never seen that before. I prefer to use the <> symbol for the "not equals" comparison operator.
From your description of the problem and your example, it's not at all clear why you need to join the table to itself.
I recommend you FIRST write a SELECT statement that returns the rows you want to update, by replacing the UPDATE and SET clauses with a SELECT <expression_list> clause, with the expression_list including the value of the primary key column(s), the column you want to update, and any other columns you want to check. Once that SELECT is returning the rows you want to update, then convert it into an UPDATE statement.

update [table_name] set channelURI = "null" where SubscriptionID = 3 or SubscriptionID =5
in this case,SubscriptionID must be a primary key.

Update table set channeluri = null where studentid <> 4
That what you want? Or you want to find all the ones that have the same uri as student 4 and null those?
Update table set channeluri = null from table inner join table t2 on table.channeluri =t2.channeluri where table.studentid <> 4 and t2.studentid =4
Something like that, im on my phone, the wife has stolen the pc

Related

Updating two values, with a second value having a where clause

This may be pointless but I want in ONE query to only the second value when Eligible equals 1, but always update the first value. So if the eligible is already 0 (or something else), don't update eligible. Can I do this in one query?
---Looping through this
UPDATE myTable p
SET p.first= 'C', p.eligible = 0
WHERE id = l_modifier_row_a.id
Desired Results
BEFORE
ID First Eligible
1 A 1
2 B 2
AFTER
ID First Eligible
1 C 0
2 C 2
In Oracle, you can use exists:
UPDATE myTable p
SET p.first = 'C',
p.eligible = 0
WHERE EXISTS (SELECT 1
FROM l_modifier_row_a l
WHERE p.id = l.id AND p.person_id = l.person_id
);
You cannot set a multiple column values sometime but not in others, in a single statement the columns are ALWAYS the same. However, you can conditionally set the value of a column to the existing value or change that value.
update mytable p
set first= 'C'
, eligible = case when p.eligible = 1
then 0
else p.eligible
end
where id = l_modifier_row_a.id ;
This might be doable in a single statement without a loop. But you did not post the loop control so I cannot look further.

Update Column Of All Rows In A Table From Another Table Using Primary Key And Foreign Key

I have a query to update all rows in a column with using of primary and foreign key relationship but the error is:
Msg 512, Level 16, State 1, Line 1
Subquery returned more than 1 value. This is not permitted when the
subquery follows =, !=, <, <= , >, >= or when the subquery is used as
an expression. The statement has been terminated.
My query is:
Update T_OP
Set DOCID = (Select DocID from T_Reg_Patients)
where Fk_RegID = (Select Pk_RegID from T_Reg_Patients)
Table1:
Pk_RegID Name DocID
1 Sam 1
2 Sam2 2
3 Sam3 3
4 Sam4 4
Table 2:
Pk_OPID Fk_RegID Name DOCID
1 1 Sam NULL
2 2 Sam2 NULL
3 3 Sam3 NULL
4 4 Sam4 NULL
I have to update the DOCID from the table 1 if the Fk_RegId(In Table 2) is same as Pk_RegID(In Table 1)...
Please help me. Thank you!
Use the below query.
UPDATE t
SET t.DOCID=p.DOCID
FROM T_OP t
JOIN T_Reg_Patients p ON p.Pk_RegID=t.Fk_RegID
Use JOIN instead:
Update T_OP
Set docid = rp.DocID
from t_op o JOIN
T_Reg_Patients rp
on o.Fk_RegID = rp.Pk_RegID;
However, there is probably no need to store DocID in both tables. Why not just use a JOIN when you need to fetch the value?
Update t2
set t2.docid=t1.DocID
from
T_Reg_Patients t1 join t_op t2 on
t2.Fk_RegID=t1.Pk_RegID
UPDATE table
SET t.DOCID=p.DOCID
FROM T_OP t
JOIN T_Reg_Patients p ON p.Pk_RegID=t.Fk_RegID
In Mysql you can use -
Update table2 t2 join table1 t1
on t2.Fk_RegID = t1.Pk_RegID
set t2.DOCID = t1.DocID;

how to properly merge these 2 query into one update?

This currently work but I would like to change the update statement to include the action of the insert below it, is it posssible?
UPDATE cas
SET [Locked] = CASE WHEN cas.Locked <> #TargetState AND cas.LastChanged = filter.SourceDateTime THEN #TargetState ELSE cas.[Locked] end,
OUTPUT inserted.Id, inserted.Locked, CASE WHEN inserted.Locked = #TargetState AND
inserted.LastChanged = filter.SourceDateTime THEN 1
WHEN inserted.LastChanged <> filter.SourceDateTime THEN -1 -- out of sync
WHEN deleted.Locked = #TargetState THEN -2 -- was not in a good state
ELSE 0 END --generic failure
INTO #OUTPUT
FROM dbo.Target cas WITH(READPAST, UPDLOCK, ROWLOCK) INNER JOIN #table filter ON cas.Id = filter.Id
INSERT INTO #OUTPUT
SELECT filter.id, NULL, when cas.id is not null -3 -- row was/is locked
else -4 end --not found
FROM #table filter left join dbo.target cas with(nolock) on filter.id = cas.id
WHERE NOT EXISTS (SELECT 1 FROM #OUTPUT result WHERE filter.id = result.UpdatedId)
I do not think what you want is possible.
You start with a table to be updated. Let’s say this table contains a set of IDs, say, 1 to 6
You join onto a temp table containing a different set of IDs that may partially overlap (say, 4 to 9)
You issue the update using an inner join. Only rows 4 to 6 are updated
The output clause picks up data only for modified rows, so you only get data for rows 4 to 6
If you flipped this to an outer join (such that all temp table rows are selected), you still only update rows 4 to 6, and the output clause still only kicks out data for rows 4 to 6
So, no, I see no way of achieving this goal in a single SQL statement.

How to update on Two Tables

I need to make an update in a table based on other information.
How to proceed?
My case is:
I have a column iniciantes table MEMB_INFO
I need to make an update MEMB_INFO SET iniciantes = 0
But I need to make a query on WHERE table column resets the character table
Example:
UPDATE MEMB_INFO
SET iniciantes = 0
FROM MEMB_INFO CROSS JOIN
Character
WHERE (Character.Resets >= 100)
necessary that the update the memb_info only occur in cases where the reference character is greater than or equal to 100
Simply, join MEMB_INFO with your Character table and specify their relations:
update m
set iniciantes = 0
from MEMB_INFO m
inner join Character c on
c.Resets >= 100
AND m.CharacterId = c.CharacterId --Specify your tables' relations.
you have to specify columns on which you're joining this two tables. If you have characterId column in both tables, your query will be:
update MEMB_INFO set
iniciantes = 0
from MEMB_INFO as m
where
m.CharacterId in (
select c.CharacterId from Character as c where c.Reset >= 100
)

What is the correct pattern for working without deferred constraints?

I am using databases that aren't Oracle or Postgresql, which means I don't have access to deferred constraints, which means that constraints must be valid at all times (instead of just on commit).
Let's say I'm storing a linked list type structure in a database like so:
id parentId
---------------
1 null
2 1
3 2
4 3
5 4
6 5
parentId is a foreign key reference to id, and is required to be unique via a constraint.
Let's say I wanted to move item 5 to sit just before item 1, so our DB would look like this:
id parentId
---------------
1 null
2 5 <-- different
3 2
4 3
5 1 <-- different
6 4 <-- different
Three rows need to be altered, which is three update statements. Any one of these update statements will cause a constraint violation: all three statements must be complete before the constraint would be valid again.
My question is: what is the best way of not violating the uniqueness constraint?
I can currently conceive of two different solutions, neither of which I like:
Set each affected parentId to null and then perform the three updates
Completely change my data model so it's more of a 'copy on write' style versioned database, where these sorts of issues are not a problem.
You can do this in a single query. I'm sure there are many variations of this, but here is what I would use...
DECLARE
#node_id INT,
#new_parent_id INT
SELECT
#node_id = 5,
#new_parent = 1
UPDATE
yourTable
SET
parent_id = CASE WHEN yourTable.id = target_node.id THEN new_antiscendant.id
WHEN yourTable.id = descendant.id THEN target_node.parent_id
WHEN yourTable.id = new_descendant.id THEN target_node.id
END
FROM
yourTable AS target_node
LEFT JOIN
yourTable AS descendant
ON descendant.parent_id = target_node.id
LEFT JOIN
yourTable AS new_antiscendant
ON new_antiscendant.id = #new_parent_id
LEFT JOIN
yourTable AS new_descendant
ON COALESCE(new_descendant.parent_id, -1) = COALESCE(new_antiscendant.id, -1)
INNER JOIN
yourTable
ON yourTable.id IN (target_node.id, descendant.id, new_descendant.id)
WHERE
target_node.id = #node_id
This will work even if the #new_parent_id is NULL or the last record in the list.
MySQL doesn't like self joins in updates, so the approach would probably be to do the LEFT JOINs into a temporary table to get the new mapping. Then join on that table to update all three recors in a single query.
INSERT INTO
yourTempTable
SELECT
yourTable.id AS node_id,
CASE WHEN yourTable.id = target_node.id THEN new_antiscendant.id
WHEN yourTable.id = descendant.id THEN target_node.parent_id
WHEN yourTable.id = new_descendant.id THEN target_node.id
END AS new_parent_id
FROM
yourTable AS target_node
LEFT JOIN
yourTable AS descendant
ON descendant.parent_id = target_node.id
LEFT JOIN
yourTable AS new_antiscendant
ON new_antiscendant.id = #new_parent_id
LEFT JOIN
yourTable AS new_descendant
ON COALESCE(new_descendant.parent_id, -1) = COALESCE(new_antiscendant.id, -1)
INNER JOIN
yourTable
ON yourTable.id IN (target_node.id, descendant.id, new_descendant.id)
WHERE
target_node.id = #node_id
UPDATE
yourTable
SET
parent_id = yourTempTable.newParentID
FROM
yourTable
INNER JOIN
yourTempTable
ON yourTempTamp.node_id = yourTable.id
(The exact syntax depends on your RDBMS.)