【问题标题】:SQL Modify questionSQL修改问题
【发布时间】:2011-06-30 09:19:03
【问题描述】:

如果不活动时间超过 30 天,我需要为 SQL 中的表替换很多值。

我有

UPDATE VERSION 
   SET isActive = 0
 WHERE customerNo = (SELECT c.VersionNo
                       FROM Activity b 
                      INNER JOIN VERSION c ON b.VersionNo = c.VersionNo
                      WHERE (Months_between(sysdate, b.Activitye) > 30));

但它只适用于一个值,如果返回的值超过一个,则返回失败。我在这里错过了什么?

如果有人能告诉我发生了什么,我也将不胜感激。

【问题讨论】:

    标签: sql oracle


    【解决方案1】:

    您使用 WHERE customerNo = (SELECT ...); 这仅适用于 1 个值。尝试使用WHERE customerNo IN (SELECT ...);

    【讨论】:

    • IN (SELECT ...) 运行非常缓慢(请参阅this post)。最好使用联接。
    • @awn:当我查看这个查询时,我认为它不会被执行很多。看起来像是每天运行的东西,所以我在这里用他自己的查询来解释它,而不是完全重写它。
    • @awn:这个问题被标记为 MySQL——这是针对 Oracle 的。
    【解决方案2】:

    处理子查询返回多行的方法有很多种。要解决的问题是返回多个值的子查询是否正确,或者它是否应该只返回一行。针对子查询的 equals 运算符期望只返回一行/记录。

    另外,MONTHS_BETWEEN 返回两个日期之间的。如果您想查看天数,请使用b.activity - SYSDATE > 30,如果合适,反之亦然。

    假设不止一行是有效的 -

    IN 子句

    子查询中不需要第二个连接到 VERSION 表:

    UPDATE VERSION 
       SET isActive = 0
     WHERE customerNo IN (SELECT c.customerno
                            FROM Activity b 
                           WHERE b.VersionNo = VERSION.VersionNo
                             AND MONTHS_BETWEEN(SYSDATE, b.activity) > 30);
    

    VERSION 表别名是指正在更新的表。

    EXISTS 子句

    UPDATE VERSION 
       SET isActive = 0
     WHERE EXISTS(SELECT NULL
                    FROM ACTIVITY a
                   WHERE VERSION.customerno = a.customerno
                     AND VERSION.versionno = a.versionno
                     AND MONTHS_BETWEEN(SYSDATE, b.activity) > 30);
    

    只能有一个?

    如果只返回一行,则可以考虑使用适当的聚合函数(MIN,MAX)。

    【讨论】:

      【解决方案3】:

      替换

      WHERE customerNo = 
      

      WHERE customerNo IN
      

      【讨论】:

        【解决方案4】:
        MERGE INTO VERSION dest
        USING (SELECT ver.VersionNo
        FROM Activity act 
        INNER JOIN VERSION ver ON act.VersionNo = var.VersionNo
        WHERE (Months_between(sysdate, act.Activitye) > 30)) src
        ON (scr.customerNo = dest.customerNo)
        WHEN MATCHED THEN
        UPDATE SET isActive = 0
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2011-01-27
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多