MySQL查询的PostgreSQL更新等价物

MySQL查询的PostgreSQL更新等价物,mysql,sql,postgresql,sql-update,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)

我有一个简单的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
我试图转换它,但它说错误的设置。我的问题是:

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_工作台

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(共享此轮)=(a.id)
    是一个语法错误。不能在括号中的
    SET
    子句中换行列名。不管怎样,它都是毫无意义的,就像
    a.id
    周围的括号一样。不过,后者不是语法错误

  • 在注释和问题更新之后,您创建了一个带有双引号
    “CamelCase”
    标识符的表(我建议永远不要使用该标识符,因为我们刚刚遇到的正是这种问题)。阅读手册中的章节,了解出了什么问题。简而言之:非标准标识符(带大写字母或保留字,…)必须始终双引号。
    为了适应新的信息,我修改了下面的查询

  • 聚合函数
    count()
    根据定义从不返回
    NULL
    <代码>合并在这种情况下毫无意义。我引述:

    应该注意的是,除了count之外,这些函数返回一个 未选择任何行时为空值

    我的。计数本身是有效的,因为
    NULL
    值不被计数,所以在没有找到
    s.id
    的地方实际上得到0

  • 我还使用了不同的列别名(
    id\u ct
    ),因为计数的
    id
    只是误导

  • 其中s.our_结果='Y'
    。。。如果
    我们的\u结果
    布尔型的
    ,就像它看起来应该是的那样,您可以简化为
    其中s.our\u结果
    。我在这里猜测,因为您没有提供必要的表定义

  • 避免实际上没有改变任何东西的更新几乎总是一个好主意(很少有例外)。我添加了第二个
    WHERE
    子句来消除这些:

    AND   w.shares_this_round IS DISTINCT FROM a.id
    
    如果
    共享\u这一轮
    定义为
    不为空
    ,则可以使用
    ,因为
    id\u ct
    不能为
    。(同样,缺少相关信息。)

  • 使用(用户名)
    只是一种可以在此处使用的符号快捷方式

  • 将所有内容放在一起,形成正确的表格:

    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
    

    你愿意花比我多得多的时间在那些OP没有发布错误消息、模式等的问题上。我确信这有助于你提高你的心理诊断能力:-),而且你比我更有耐心。@CraigRinger:心理是一个很好的提示。:)所有缺少的基本信息使人们有时似乎确实相信灵媒。但让我引用一句话:“没有灵媒。”在这种特殊情况下,考虑到多重语法错误,将其诊断为“语法有效”可能有点草率。解析器比我意识到的更具阶段性。如果要更新的表不存在,它会很早就爆炸出来,并且不会费心解析查询的其余部分——以获得实际上不可解析的位。创建表证实了这一点。至于精神方面;我使用它的意思是“心理调试”,指的是使用经验、耐心和推理在信息不足的情况下进行调试,所以看起来你几乎只是用假定的心理能力来找出答案;-)@CraigRinger-我很抱歉发布了一个不完整的问题,但我真的有3天没睡觉了,我的头一直在砰砰作响,所以我想不出正确的程序,很抱歉,我将确保下次不会发生这种情况。@ErwinBrandstetter-感谢您对其进行了如此深入的解释,尽管错误如下:错误:p.associateduserid列不存在第4行:选择p.associateduserid,计数(s.id)作为身份证,我会更新schema@ErwinBrandstetter-哦,真的很抱歉,我已经更新了问题+1,感谢您的跟进和更新。@CraigRinger-np,只是我对这个问题非常感兴趣,正在研究比特币前端,所以即使添加了表定义,也没有太多时间呼吸,这现在是一个好问题。下次,记住也要包括程序版本。大部分时间都是相关的。是的,我只是我快要晕倒了,所以想不清楚