通过一些模糊的错误(可能在我身边)对年度的变化我在我的表中列出了值“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 ?我该如何解决我的问题?
谢谢!亚历
更新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年至2011年可能是2011年年初的正确值。
答案 0 :(得分:1)
您需要确保子查询只返回一行(如错误消息所示)。您的示例数据未显示此信息,但显然您的表中有 yw ='2011-01'的多行。
如果id
列是主键(或其中的一部分),则将其添加到内部选择将解决此问题。
update pref_money set money=money + (select money from pref_money m2 where m2.yw = '2011-52' and m2.id = pref_money.id) where yw='2011-01';
答案 1 :(得分:0)
嗯,这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开始。 01/01/2011& 02/01/2011真的是在第52周!
答案 2 :(得分:0)
其中一种可能性是使用聚合并执行以下操作:
update pref_money as pm
set money = money+money_delta
from ( select id, sum(money) as money_delta
from pref_money as pmt
where yw > '2011-01' -- here you should include only the records, that are really corrupted
-- for the example of the data from you, text > should work
group by id) as pmd
where pm.id = pmd.id;
and pm.yw = '2010-01';
但说实话,我会为date
字段使用yw
数据类型,并设置约束date_trunc('month', yw)::date = yw
以确保yw
中的日期仅为这个月的第一天。
答案 3 :(得分:0)
我最终做了:
# update pref_money as m1 set money=money+
coalesce((select money from pref_money as m2
where m1.id=m2.id and m2.yw='2011-52'),0)
where m1.yw='2010-52';
UPDATE 2081
# delete from pref_money where yw='2011-52';
DELETE 1223
我应该首先使用 IYYY-IW 代替YYYY-IW - 从pgsql-general@postgresql.org邮件列表中获得两个提示