【问题标题】:Update my database from Select result从选择结果更新我的数据库
【发布时间】:2012-03-28 19:38:05
【问题描述】:
mysql> SELECT Ext, Pass, Name, Context FROM temp_Users WHERE temp_Users.Pass NOT IN (SELECT Pass FROM Users);
+------+-------+---------+------------+
| Ext  | Pass  | Name    | Context    |
+------+-------+---------+------------+
| 6003 | Hello | WebPone | DLPN_Admin |
+------+-------+---------+------------+
1 row in set (0.00 sec)


mysql> UPDATE Users
    -> SET (Pass, Name, Context) = (SELECT  Pass, Name, Context FROM temp_Users WHERE temp_Users.Pass NOT IN (SELECT Pass FROM Users))
    -> WHERE Users.Ext = temp.Ext;
ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '(Pass, Name, Context) = (SELECT  Pass, Name, Context FROM temp_Users WHERE temp_' at line 2

我想从选择结果更新我的数据库,但我收到了这个错误。请告诉我如何解决?

【问题讨论】:

  • 不要粗鲁,但你的尝试甚至没有接近。看起来你写了你希望的语法,instead of checking what the actual syntax is...
  • @MichaelFredrickson:平心而论,有些 DBMS 支持类似于 OP 的语法。如果(s)他在谷歌上搜索“SQL”更新语句而不是“MySQL”更新语句,(s)他很可能会得到类似的结果。 (不是每个人都知道不同的 SQL 方言有多么不同。)
  • @ruakh 有趣,我的立场是正确的。只是出于好奇,您知道哪种 SQL 方言允许这样做吗?
  • @MichaelFredrickson:甲骨文有。 (我最初写了“DBMSes”,复数,因为我认为 PostgreSQL 也可以,但现在我看到虽然 PostgreSQL 支持 SET (a, b, c) = (d, e, f),但它不允许你用 single(d, e, f) 部分/i> 子查询返回 multiple 字段。我想差异的原因是 MySQL 和 PostgreSQL 都提供类似“join”的 UPDATE 语法,Oracle 没有,所以它弥补了通过提供将多个字段设置为多字段子查询的语法。)
  • @MichaelFredrickson 请看一下这个链接stackoverflow.com/questions/1003011/…

标签: mysql sql database


【解决方案1】:

MySQL 不支持 UPDATE 语句的 SET ( multiple_fields ) = ( subquery_that_returns_multiple_fields ) 语法。相反,您必须使用“多表”更新(连接)。见http://dev.mysql.com/doc/refman/5.6/en/update.html

您的查询还有其他一些问题,所以我不清楚究竟你想要什么。 . .但我认为你想要这样的东西:

UPDATE users
  JOIN temp_users
    ON temp_users.ext = users.ext
   SET users.pass = temp_users.pass,
       users.name = temp_users.name,
       users.context = temp_users.context
 WHERE temp_users.pass NOT IN
        -- extra subquery to bypass MySQL limitation:
        ( SELECT pass
            FROM ( SELECT pass
                     FROM users
                 ) t
        )
;

【讨论】:

  • +1 @ruakh,你在这两个方面都是对的......你必须在左边有前缀,否则它会抱怨它不明确,你必须添加额外的子查询IN.
  • @ruakh 非常感谢先生,您的回答完成了我的工作:)
【解决方案2】:
UPDATE Users u
JOIN temp_Users tu ON tu.Ext = u.Ext
SET 
    Pass = tu.Pass,
    Name = tu.Name,
    Context = tu.Context
WHERE tu.Pass NOT IN (
    SELECT Pass
    FROM Users
)

【讨论】:

  • 先生,如果我不仅要保留 i 更改密码,我还需要保留 i 名称和上下文,那么我该怎么办?
  • 你确定你可以写例如Pass = tu.Pass 而不是 u.Pass = tu.Pass?这对我来说似乎很奇怪。当Users 是要更新的表之一时,您确定可以在顶层拥有NOT IN (SELECT Pass FROM Users) 吗?文档指出“目前,您无法更新表并在子查询中从同一个表中进行选择。”
  • @ruakh 好问题,我会仔细检查。我知道在 SQL Server 中,如果您尝试在更新中为赋值的左侧添加前缀,但不确定 MySql。我还会仔细检查IN 的有效性。
猜你喜欢
  • 2014-09-12
  • 2021-04-03
  • 2016-07-03
  • 2012-11-17
  • 1970-01-01
  • 2012-12-10
  • 1970-01-01
  • 1970-01-01
  • 2023-03-17
相关资源
最近更新 更多