Question

I have a MSSQL table that contains rows, some of which I need to update, depending upon the absence/presence of other rows in the same table. the table and sample data look like this:

SQL Table:

    TABLE tblConnector(
      ID1 [int] NOT NULL,
      ID2 [int] NOT NULL,
      ID3 [int] NOT NULL,
      ...other cols...)

having PRIMARY KEY CLUSTERED comprised of ID1, ID2 and ID3 - meaning that the compound key must be unique.

Data Structure:

ID1  ID2  ID3

111  222  1
111  222  9999
333  444  1    <--- update only this row
555  666  1        
555  666  9999
777  888  2
777  888  9999 
123  456  3    <--- don't update this row

I need to update any row in this table, setting ID3 = 9999, where ID3 currently is 1 and there are no other rows in the table with the same values for ID1 and ID2, with ID3 = 9999.

In my sample data, I only want to update the 3rd row, setting ID3 = 9999 - because it has ID3 = 1 and there are no other rows in the table with the same ID1 and ID2 values (where ID3 <> 1). I don't want to update the last row - so using count() to isolte rows isn't a valid approach.

I've tried numerous attempts to join the table to itself, but I can't seem to get an UPDATE statement that will only affect the rows I want.

Any advice on how to code this SQL?

UPDATE: I should have been more clear - I want to update the ID3 column to 9999 ONLY if the current value in ID3 is 1 ... AND there are no other rows that have the same ID1 and ID2 values and ID3 = 9999. ID1, ID2 and ID3 comprise a unique key and setting 9999 in ID3 can't duplicate a key value already in existence.

Was it helpful?

Solution

Maybe I'm reading that differently.

;WITH cte AS (
  SELECT ID1, ID2
    FROM tblConnector
   GROUP BY ID1, ID2
  HAVING COUNT(1) = 1
)
UPDATE tblConnector 
   SET ID3 = 9999
  FROM tblConnector a
       INNER JOIN
       cte b ON a.ID1 = b.ID1
            AND a.ID2 = b.ID2

sqlfiddle

EDIT (after comment)

Added your new sample records and WHERE ID3 = 1 to the UPDATE. In this case 1 is a placeholder for whatever single value you want to plugin.

;WITH cte AS (
  SELECT ID1, ID2
    FROM tblConnector
   GROUP BY ID1, ID2
  HAVING COUNT(1) = 1
)
UPDATE tblConnector 
   SET ID3 = 9999
  FROM tblConnector a
       INNER JOIN
       cte b ON a.ID1 = b.ID1
            AND a.ID2 = b.ID2
 WHERE ID3 = 1

New fiddle

OTHER TIPS

Following your exact wording, the following should work:

UPDATE tblConnector t1
SET ID3 = 9999
WHERE NOT EXISTS
(
    SELECT 1
    FROM tblConnector t2
    WHERE t2.ID1 = t1.ID1
    AND t2.ID2 = t1.ID2
    AND t2.ID3 <> 9999
)

Without EXISTS, without CTE approach. I don't know if this will be most efficient.

update t1
set t1.id3 = 9999 
--select *
from
tblConnector as t1 
left join
(
select id1, id2, COUNT(id1) as Rowz
from tblConnector as t2
group by id1, id2
) as src
on t1.id1 = src.id1
where Rowz = 1
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top