PostgreSQL UPDATE相当于MySQL查询

我有一个简单的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

我试图转换它,但它说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

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

     ------------------------------EDIT-------------------------------------

股份表

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
);

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
);

pool_workes表

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

解决方法:

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

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

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

>缺少webuser的别名u.一个微不足道的错误.
>缺少w和a之间的连接.结果是交叉连接,这几乎没有任何意义,就性能而言是一个非常昂贵的错误.它也完全不需要,您可以从查询删除冗余的webuser第二个实例.
> SET(shares_this_round)=(a.id)是语法错误.您不能在括号中的SET子句中包装列名.无论如何,这都是毫无意义的,就像a.id周围的括号一样.但后者不是语法错误.
>事实证明,在评论和问题更新之后,您使用双引号“CamelCase”标识符创建了表格(我建议不要使用它,因为我们刚遇到的问题就是这样).阅读手册中的第Identifiers and Key Words章,了解出了什么问题.简而言之:非标准标识符(带大写字母或保留字,……)必须始终双引号.
修改了下面的查询以适应新信息.
>根据定义,聚合函数count()永远不会返回NULL.在这种背景下,COALESCE毫无意义.我引用the manual on aggregate functions

It should be noted that except for count, these functions return a
null value when no rows are selected.

强调我的.计数本身有效,因为不计算NULL值,所以实际上在没有找到s.id的情况下得到0.
>我还使用了不同的列别名(id_ct),因为计数的id只是误导.
> WHERE s.our_result =’Y’…如果our_result的类型为boolean,就像它应该是的那样,你可以简化为WHERE s.our_result.我在这里猜测,因为你没有提供必要的表定义.
>避免实际上没有改变任何内容的UPDATE几乎总是一个好主意(很少有例外情况适用).我添加了第二个WHERE子句来消除这些:

AND   w.shares_this_round IS disTINCT FROM a.id

如果shares_this_round定义为NOT NULL,则可以使用<>相反,因为id_ct不能为NULL. (再次,缺少有问题的信息.)
> USING(用户名)只是一个可以在这里使用的符号快捷方式.

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

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

相关文章

项目需要,有个数据需要导入,拿到手一开始以为是mysql,结果...
本文小编为大家详细介绍“怎么查看PostgreSQL数据库中所有表...
错误现象问题原因这是在远程连接时pg_hba.conf文件没有配置正...
因本地资源有限,在公共测试环境搭建了PGsql环境,从数据库本...
wamp 环境 这个提示就是说你的版本低于10了。 先打印ph...
psycopg2.OperationalError: SSL SYSCALL error: EOF detect...