我可以使用1个SQL语句更新多个记录,其中更新值取决于要更新的​​记录吗?

时间:2011-05-18 13:00:05

标签: sql sql-update records

鉴于有2个表:

  1. STATES(保存可用状态列表) - key field = STATE_ID。另一个关键是DOMAIN_ID,STATE_NAME。因此,存在具有相同STATE_NAME但不同DOMAIN_ID的记录。
  2. OBJECTS(保存所有对象的列表,每个对象都有自己的状态) - key field = OBJECT_ID。还包含字段STATE_ID。
  3. 假设我有一个大约1000个对象的列表,需要更新到状态" CLOSED"在各自的领域。

    对于一个单个对象(比如OBJECT_ID 12345),我可以使用SQL语句:

    update OBJECTS
    set STATE_ID =
    (
      select STATE_ID from STATES
      where STATE_NAME= 'CLOSED'
      and DOMAIN_ID =
      (
        select DOMAIN_ID from STATES a, OBJECTS b
        where a.STATE_ID = b.STATE_ID and b.OBJECT_ID = 12345)
      )
    ) where OBJECT_ID = 12345
    

    是否可以使用一个语句来更新多个对象?问题的症结似乎是我无法在SQL语句中的两个位置定义OBJECT_ID。

    由于显而易见的原因,以下陈述不起作用:

    update OBJECTS
    set STATE_ID =
    (
      select STATE_ID from STATES
      where STATE_NAME= 'CLOSED'
      and DOMAIN_ID =
      (
        select DOMAIN_ID from STATES a, OBJECTS b
        where a.STATE_ID = b.STATE_ID and b.OBJECT_ID in
        (
          select distinct OBJECT_ID from OBJECTS_TO_UPDATE
        )
      )
    ) where OBJECT_ID in (select distinct OBJECT_ID from OBJECTS_TO_UPDATE)
    

    有人可以给我一些暗示我可以做些什么来解决这个问题吗?

    谢谢。

3 个答案:

答案 0 :(得分:0)

您可以使用表名OBJECTS,因为它在范围内,例如

UPDATE OBJECTS
  SET STATE_ID = (
                  SELECT STATE_ID 
                    FROM STATES
                   WHERE STATE_NAME = 'CLOSED'
                         AND DOMAIN_ID = (
                                          SELECT DOMAIN_ID 
                                            FROM STATES a, 
                                                 OBJECTS b
                                           WHERE a.STATE_ID = b.STATE_ID 
                                                 AND b.OBJECT_ID = OBJECTS.OBJECT_ID
                                         )
                 )
 WHERE EXISTS (
               SELECT * 
                 FROM STATES
                WHERE STATE_NAME = 'CLOSED'
                      AND DOMAIN_ID = (
                                       SELECT DOMAIN_ID 
                                         FROM STATES a, 
                                              OBJECTS b
                                        WHERE a.STATE_ID = b.STATE_ID 
                                              AND b.OBJECT_ID = OBJECTS.OBJECT_ID
                                      )
                 );

答案 1 :(得分:0)

SQL Server,MS Access ,(MySQL?)解决方案:

我认为这样做了。您可能希望先将UPDATESET子句替换为SELECT *,然后检查结果集是否正确:

update o
set STATE_ID = s_closed.STATE_ID
from
   Objects o
      inner join
   States s_current
      on
         o.STATE_ID = s.STATE_ID
      inner join
   States s_closed
      on
         s_current.DOMAIN_ID = s_closed.DOMAIN_ID and
         s_closed.STATE_NAME = 'Closed'
      inner join
   OBJECTS_TO_UPDATE otu
      on
         otu.OBJECT_ID= o.OBJECT_ID

答案 2 :(得分:0)

在不了解更多关于表结构的情况下,我无法确定您需要什么SQL。但是获取新STATE_ID的子查询可以(如上所述)引用您正在更新的表...

例如......

update
  OBJECTS
set
  STATE_ID =
    (
      select
        NEW_STATE.STATE_ID
      from
        STATES    AS OLD_STATE
      inner join
        STATES    AS NEW_STATE
          ON NEW_STATE.DOMAIN_ID = OLD_STATE.DOMAIN_ID
      where
        OLD_STATE.STATE_ID = OBJECTS.STATE_ID
        AND NEW_STATE.STATE_NAME = 'CLOSED'
    )
where
  OBJECT_ID in (select distinct OBJECT_ID from OBJECTS_TO_UPDATE)

通过这种方式,您可以确保子查询仅为OBJECTS表中的任何给定记录返回一个STATE_ID。