使用子查询派生表错误更新

Posted

技术标签:

【中文标题】使用子查询派生表错误更新【英文标题】:Update with Sub Query Derived Table Error 【发布时间】:2012-08-06 12:44:14 【问题描述】:

我有以下 SQL 语句来简单地使用 Sybase 15 数据库中的最新包版本号更新 #temp 临时表。

UPDATE t
SET versionId = l.latestVersion
FROM #temp t INNER JOIN (SELECT gp.packageId
                                , MAX(gp.versionId) latestVersion
                         FROM Group_Packages gp 
                         WHERE gp.groupId IN (SELECT groupId 
                                              FROM User_Group 
                                              WHERE userXpId = 'someUser')
                         GROUP BY gp.packageId) l
ON t.packageId = l.packageId

对我来说(主要是 Oracle 和 SQL Server 的经验比 Sybase 多)这句话没有什么问题。但是,Sybase 会抛出异常:

You cannot use a derived table in the FROM clause of an UPDATE or DELETE statement.

现在,我不明白这里有什么问题。我认为这是因为使用了聚合 / GROUP BY。当然,我可以将子查询放在临时表中并加入它,但我真的很想知道“正确”的方法应该是什么,到底是什么错误。

任何想法或指导将不胜感激。

【问题讨论】:

【参考方案1】:

我猜这是UPDATEFROM 子句中Sybase 的限制(不允许派生表)。也许你可以这样重写:

UPDATE t
SET t.versionId = l.versionId
FROM #temp t
  INNER JOIN 
    Group_Packages l
      ON t.packageId = l.packageId
WHERE
    l.groupId IN ( SELECT groupId 
                   FROM User_Group 
                   WHERE userXpId = 'someUser')
  AND
    l.versionId =
        ( SELECT MAX(gp.versionId)
          FROM Group_Packages gp 
          WHERE gp.groupId IN ( SELECT groupId 
                                FROM User_Group 
                                WHERE userXpId = 'someUser')
            AND gp.packageId = l.packageId
        ) ;

【讨论】:

这似乎是一个。谢谢你。只需稍作调整:UPDATE tUPDATE #temp。令人沮丧的是,这么简单的东西必须以这种方式编写! 我认为@valexhome 提供了一个更短的版本。【参考方案2】:

SYBASE 似乎不支持 UPDATE FROM 类中的嵌套查询。 Similar problem

尝试使用这个:

UPDATE #temp
SET versionId =  (SELECT MAX(gp.versionId) latestVersion
                         FROM Group_Packages gp 
                         WHERE gp.packageId=#temp.packageId
                                and
                               gp.groupId IN (SELECT groupId 
                                              FROM User_Group 
                                              WHERE userXpId = 'someUser')

                         )

如果 l.latestVersion 为 NULL 怎么办?你想用 null 更新 #temp 吗?如果没有,则添加 WHERE:

    WHERE (SELECT MAX(gp.versionId)
                          ....
                                 ) is not null

【讨论】:

【参考方案3】:

#temp 的表别名称为“t”,原始表称为“t”。

我的猜测是这就是问题所在。

我想你想开始:

update #temp

【讨论】:

以上是关于使用子查询派生表错误更新的主要内容,如果未能解决你的问题,请参考以下文章

使用子查询与派生表进行内部联接

MySQL-子查询,派生表,通用表达式

为啥 CTE 比游标/派生表/子查询/临时表等更好?

ORDER BY 子句在视图、内联函数、派生表、子查询和公用表表达式中无效,除非 TOP、OFFSET 或 FOR XML

ORDER BY 子句在视图、内联函数、派生表、子查询和公用表表达式中无效

那个mysql 子查询和连接查询 一般常用哪个 谁效率高些