PostgreSQL:将一行的值添加到另一行并删除前一行
通过一些模糊的错误(可能在我这边),在年份的变化中,我的表中得到了值“2011-52”(列出了玩家在一周内赢得的虚拟货币),这些值实际上属于“2011-01” :
# select * from pref_money where id='OK324712148886';
id | money | yw
----------------+-------+---------
OK324712148886 | 203 | 2010-46
OK324712148886 | 219 | 2010-49
OK324712148886 | 115 | 2010-51
OK324712148886 | 63 | 2011-52
OK324712148886 | 20 | 2011-01
要解决这个问题,我想将 yw='2011-52' 行的值 (63) 添加到 yw='2011-01' 行的值 (20),然后删除前一行,对于表中的每个 id。
所以我正在尝试(使用 PostgreSQL 8.4.6 / CentOS 5.5):
# update pref_money set money=money+
(select money from pref_money where yw='2011-52')
where yw='2011-01';
ERROR: more than one row returned by a subquery used as an expression
这可能是因为我需要在子查询的圆括号内指定 id ?请问我该如何解决我的问题?
谢谢你! Alex
更新2:
我也尝试过:
# update pref_money set money=money+
(select money from pref_money m2 where m2.yw='2011-52' and id=m2.id)
where yw='2011-01';
ERROR: more than one row returned by a subquery used as an expression
和
# update pref_money m1 set m1.money=m1.money+
(select money from pref_money m2 where m2.yw='2011-52' and m1.id=m2.id)
where m1.yw='2011-01';
ERROR: column "m1" of relation "pref_money" does not exist
LINE 1: update pref_money m1 set m1.money=m1.money+(select money fro...
并且:
# update pref_money as m1 set money=money+
(select coalesce(money,0) from pref_money as m2
where m1.id=m2.id and m2.yw='2011-52')
where m1.yw='2011-01';
ERROR: null value in column "money" violates not-null constraint
我的表定义是:
# \d pref_money
Table "public.pref_money"
Column | Type | Modifiers
--------+-----------------------+-----------------------------------------
id | character varying(32) |
money | integer | not null
yw | character(7) | default to_char(now(), 'YYYY-IW'::text)
Indexes:
"pref_money_yw_index" btree (yw)
Foreign-key constraints:
"pref_money_id_fkey" FOREIGN KEY (id) REFERENCES pref_users(id)
当然我有数千行具有不同的id,或者我只是手动修复1个值并且不会'不要在 Stackoverflow 上提问。
我不同意这样的评论,即 2011-52 可能是 2011 年初的正确值。
through some obscure error (probably on my side) over the change of the year I've got values "2011-52" in my table (listing virtual money won by players in a week), which actually belong under "2011-01":
# select * from pref_money where id='OK324712148886';
id | money | yw
----------------+-------+---------
OK324712148886 | 203 | 2010-46
OK324712148886 | 219 | 2010-49
OK324712148886 | 115 | 2010-51
OK324712148886 | 63 | 2011-52
OK324712148886 | 20 | 2011-01
To fix that I would like to add the value (63) from the row with the yw='2011-52' to the value (20) of the row with the yw='2011-01' and then drop the former row, for each id in the table.
So I am trying (using PostgreSQL 8.4.6 / CentOS 5.5):
# update pref_money set money=money+
(select money from pref_money where yw='2011-52')
where yw='2011-01';
ERROR: more than one row returned by a subquery used as an expression
this is probably because I need to specify the id too inside the round brackets of the subquery? How can I fix my query please?
Thank you! Alex
UPDATE 2:
I've also tried:
# update pref_money set money=money+
(select money from pref_money m2 where m2.yw='2011-52' and id=m2.id)
where yw='2011-01';
ERROR: more than one row returned by a subquery used as an expression
and
# update pref_money m1 set m1.money=m1.money+
(select money from pref_money m2 where m2.yw='2011-52' and m1.id=m2.id)
where m1.yw='2011-01';
ERROR: column "m1" of relation "pref_money" does not exist
LINE 1: update pref_money m1 set m1.money=m1.money+(select money fro...
and:
# update pref_money as m1 set money=money+
(select coalesce(money,0) from pref_money as m2
where m1.id=m2.id and m2.yw='2011-52')
where m1.yw='2011-01';
ERROR: null value in column "money" violates not-null constraint
And my table definition is:
# \d pref_money
Table "public.pref_money"
Column | Type | Modifiers
--------+-----------------------+-----------------------------------------
id | character varying(32) |
money | integer | not null
yw | character(7) | default to_char(now(), 'YYYY-IW'::text)
Indexes:
"pref_money_yw_index" btree (yw)
Foreign-key constraints:
"pref_money_id_fkey" FOREIGN KEY (id) REFERENCES pref_users(id)
And of course I have thousands of rows with different id's or I'd just fix 1 value by hand and wouldn't ask here a question at Stackoverflow.
And I don't agree with the comment, that 2011-52 could be a correct value at the beginning of the year 2011.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
您需要确保子查询恰好返回一行(如错误消息所示)。您的示例数据没有显示这一点,但显然您的表格中有不止一行带有 yw='2011-01' 的行。
如果 id 列是主键(或其一部分),那么将其添加到内部选择将纠正此问题。
You need to make sure that the subquery returns exactly one row (as the error message suggests). Your sample data doesn't show this, but apparently there is more than one row with yw='2011-01' in your table.
If the
id
column is the primary key (or part of it), then yes adding that to the inner select will rectify this problem.嗯,这个 52 也许并不是真正的错误。 201 年的第一周在 ISO 年份中实际上编号为 52。有时是 0,有时是 52。 http://en.wikipedia.org/wiki/ISO_week_date 。
因此,也许您不想要本周的 ISO 编号,因为在按顺序查询时这可能会出现问题。或者尝试将 2011-52 更改为 2010-52。
并且不要合并 2011-52 和 2011-01,2011-01 从 03/01/2011 开始。 2011 年 1 月 1 日02/01/2011 确实是第 52 周!
Well, this 52 is maybe not really an error. The first week of this 201 year is really numbered 52 in ISO year. Sometimes it's 0, sometimes it's 52. http://en.wikipedia.org/wiki/ISO_week_date.
So maybe you do not want the ISO number of the week, as it can be a problem when doing order by queries, maybe. Or try to change 2011-52 to 2010-52.
And do not merge 2011-52 and 2011-01, 2011-01 start on 03/01/2011. 01/01/2011 & 02/01/2011 are really in week 52 !
一种可能性是使用聚合并执行类似的操作:
但说实话,我会为
yw
字段使用date
数据类型并设置约束date_trunc('month', yw)::date = yw
以确保yw
中的日期仅为该月的第一天。One of the possibilities would be to use an aggregate and do something like:
But to say the truth, I would use a
date
data type for theyw
field and set a constraintdate_trunc('month', yw)::date = yw
to ensure the date inyw
is only the first day of the month.我最终做了:
我应该首先使用 IYYY-IW 而不是 YYYY-IW - 从 [电子邮件受保护] 邮件列表
I've ended up doing:
And I should have used IYYY-IW instead of YYYY-IW in the 1st place - got both hints from [email protected] mailing list