感谢您抽出宝贵时间来查看我的问题。 我见过类似的问题,但深度不一样。请帮忙!
我想更新一个表中包含user_id和date_created的表中的所有行,其中user_id的date_created最低。
以下选项为我提供了我想要更新的所有行:
select user_id, min(date_created) from mytable s1 where
(select count(1) from mytable s2 where
s1.user_id = s2.user_id group by s2.user_id)
> 1 group by user_id order by user_id;
我原本希望这次更新有效:
update mytable set join_status = 1 where date_created =
(select min(date_created) from mytable s1 where
(select count(1) from simplepay_payment s2 where
s1.user_id = s2.user_id group by s2.user_id)
> 1 group by user_id);
但是给出了以下错误:
ERROR: more than one row returned by a subquery used as an expression
我尝试了一些不同的解决方案,但似乎没有任何帮助。
有人对我有任何想法吗?
再次感谢。
答案 0 :(得分:3)
将您的SQL更改为:
update mytable set join_status = 1 where date_created IN
(select min(date_created) from mytable s1 where
(select count(1) from simplepay_payment s2 where
s1.user_id = s2.user_id group by s2.user_id)
> 1 group by user_id);
详细了解the docs中的行比较。
修改强>
在子查询中,您正在执行GROUP BY user_id
。这意味着 将根据simplepay_payment
表中唯一user_id值的数量接收多行。
要使查询按预期工作,您应该使用2列加入:user_id
和date_created
。正如您所提到的,您已经拥有了可以提供正确结果的查询,因此您可以像这样使用它:
WITH desired AS (
SELECT user_id, min(date_created) AS mindt
FROM mytable s1 where
(SELECT count(1) FROM mytable s2
WHERE s1.user_id = s2.user_id GROUP BY s2.user_id) > 1
GROUP BY user_id)
UPDATE mytable m SET join_status = 1 FROM desired d
WHERE d.user_id = m.user_id AND d.mindt = m.date_created;
我已将您的查询包含在Common Table Expression中,并在UPDATE
语句中使用它。您可以在查询末尾添加RETURNING m.*
,以查看已更新的行及其新值。
您可以在SQL Fiddle上测试此查询。
<强> EDIT2:强>
在UPDATE
语句的9.1版之前,公用表表达式(WITH-queries)不可用。您只需将CTE子查询移动到更新中,如下所示:
UPDATE mytable m SET join_status = 1 FROM (
SELECT user_id, min(date_created) AS mindt
FROM mytable s1 where
(SELECT count(1) FROM mytable s2
WHERE s1.user_id = s2.user_id GROUP BY s2.user_id) > 1
GROUP BY user_id) d
WHERE d.user_id = m.user_id AND d.mindt = m.date_created;