PostgreSQL UPDATE相当于MySQL查询

Kes*_*air 3 mysql sql postgresql sql-update

我有一个简单的MySQL查询,我想转换为PostgreSQL.3天后我终于退出了,因为我不明白这里有什么不妥:

UPDATE webUsers u, 
(SELECT IFNULL(count(s.id),0) AS id, p.associatedUserId FROM pool_worker p 
LEFT JOIN shares s ON p.username=s.username 
WHERE s.our_result='Y' GROUP BY p.associatedUserId) a
SET shares_this_round = a.id WHERE u.id = a.associatedUserId
Run Code Online (Sandbox Code Playgroud)

我试图转换它,但它说SET上的错误.这是我的查询:

UPDATE webusers 
SET (shares_this_round) = (a.id)
FROM (SELECT coalesce(count(s.id),0) AS id, p.associatedUserId FROM pool_worker p 
LEFT JOIN shares s ON p.username=s.username WHERE s.our_result='Y' GROUP BY p.associatedUserId) a, webusers w WHERE u.id = a.associatedUserId
Run Code Online (Sandbox Code Playgroud)

谁能告诉我它有什么问题?因为这个原因,我无法入睡.

     ------------------------------EDIT-------------------------------------
Run Code Online (Sandbox Code Playgroud)

股份表

CREATE TABLE shares (
id bigint NOT NULL,
rem_host character varying(255) NOT NULL,
username character varying(120) NOT NULL,
our_result character(255) NOT NULL,
upstream_result character(255),
reason character varying(50),
solution character varying(1000) NOT NULL,
"time" timestamp without time zone DEFAULT now() NOT NULL
);
Run Code Online (Sandbox Code Playgroud)

webusers表

CREATE TABLE webusers (
id integer NOT NULL,
admin integer NOT NULL,
username character varying(40) NOT NULL,
pass character varying(255) NOT NULL,
email character varying(255) NOT NULL,
"emailAuthPin" character varying(10) NOT NULL,
secret character varying(10) NOT NULL,
"loggedIp" character varying(255) NOT NULL,
"sessionTimeoutStamp" integer NOT NULL,
"accountLocked" integer NOT NULL,
"accountFailedAttempts" integer NOT NULL,
pin character varying(255) NOT NULL,
share_count integer DEFAULT 0 NOT NULL,
stale_share_count integer DEFAULT 0 NOT NULL,
shares_this_round integer DEFAULT 0 NOT NULL,
api_key character varying(255),
"activeEmail" integer,
donate_percent character varying(11) DEFAULT '1'::character varying,
btc_lock character(255) DEFAULT '0'::bpchar NOT NULL
);
Run Code Online (Sandbox Code Playgroud)

pool_workes表

CREATE TABLE pool_worker (
id integer NOT NULL,
"associatedUserId" integer NOT NULL,
username character(50),
password character(255),
allowed_hosts text
);
Run Code Online (Sandbox Code Playgroud)

Erw*_*ter 5

首先,我格式化以达到这个不那么令人困惑但仍然不正确的查询:

UPDATE webusers 
SET   (shares_this_round) = (a.id)
FROM  (
   SELECT coalesce(count(s.id),0) AS id, p.associatedUserId
   FROM   pool_worker p 
   LEFT   JOIN shares s ON p.username=s.username
   WHERE  s.our_result='Y'
   GROUP  BY p.associatedUserId) a
   , webusers w
WHERE u.id = a.associatedUserId
Run Code Online (Sandbox Code Playgroud)

此语句中有多个不同的错误和更多次优部分.错误首先出现并 大胆强调.最后几项只是建议.

  1. 缺少 u webuser的别名.一个微不足道的错误.

  2. 缺少加入之间wa.结果是交叉连接,这几乎没有任何意义,就性能而言是一个非常昂贵的错误.它也完全不需要,您可以从查询中删除冗余的第二个实例webuser.

  3. SET (shares_this_round) = (a.id)语法错误.您不能SET在括号中的子句中包装列名.无论如何,这都是毫无意义的,就像周围的括号一样a.id.但后者不是语法错误.

  4. 事实证明,在评论和问题更新之后,您创建了带有双引号"CamelCase"标识符的表格(我建议不要使用,因为我们刚遇到的问题就是这样).阅读手册中的标识符和关键字一章,了解出了什么问题.简而言之:非标准标识符(带大写字母或保留字,......)必须始终双引号.
    我修改了下面的查询以适应新信息.

  5. 根据定义,聚合函数count()永远不会返回NULL.COALESCE在这种背景下毫无意义.我引用了关于聚合函数的手册:

    应该注意,除了count之外,这些函数在没有选择行时返回空值.

    强调我的.计数本身有效,因为NULL不计算值,所以实际上在没有s.id找到值的情况下得到0 .

  6. 我还使用了不同的列别名(id_ct),因为id计数只是误导.

  7. WHERE s.our_result = 'Y'...如果our_result是类型boolean,就像它应该是,你可以简化到公正WHERE s.our_result.我在这里猜测,因为你没有提供必要的表定义.

  8. 避免实际上没有改变任何东西的UPDATE几乎总是一个好主意(很少有例外情况适用).我添加了第二个WHERE条款来消除这些:

    AND   w.shares_this_round IS DISTINCT FROM a.id
    
    Run Code Online (Sandbox Code Playgroud)

    如果shares_this_round已定义NOT NULL,则可以使用,<>因为id_ct不能NULL.(再次,缺少有问题的信息.)

  9. USING(username) 只是一个可以在这里使用的符号快捷方式.

将所有内容放在一起以达到这种正确的形式:

UPDATE webusers w
SET    shares_this_round = a.id_ct
FROM  (
   SELECT p."associatedUserId", count(s.id) AS id_ct
   FROM   pool_worker p 
   LEFT   JOIN shares s USING (username)
   WHERE  s.our_result = 'Y'                        -- boolean?
   GROUP  BY p."associatedUserId"
   ) a
WHERE w.id = a."associatedUserId"
AND   w.shares_this_round IS DISTINCT FROM a.id_ct  -- avoid empty updates
Run Code Online (Sandbox Code Playgroud)

  • 你愿意花费更多的时间来讨论OP没有发布错误信息,架构等的问题.我相信它可以帮助你提高你的心理诊断能力:-)而且你是一个比我更耐心的人. (3认同)