2012-05-16 44 views
0

感謝您花時間查看我的問題。 我見過類似的問題,但深度不一樣。請幫忙!Postgresql更新基於計數,分鐘和組

我想更新一列中的所有行,其中包含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

您是否還想設置date_created,或者只有join_status? –

+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_iddate_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:

通用表表達式(WITH查詢)不是9.1版本UPDATE語句之前可用。您可以簡單地將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; 
+0

感謝您的快速回答!我真的想匹配每個user_id的min_ date_created行,因爲date_created可能不是唯一的。所以我想爲子查詢獲得一行。你有什麼建議嗎? – hgolov

+0

這太棒了!非常感謝您的解決方案和鏈接到小提琴!問題:使用您的建議構建的查詢在版本9.1.3的小提琴中工作,但不在我的8.4.11服務器上。有任何想法嗎?我收到的錯誤是在更新或更新附近的語法錯誤。以下是更新後的查詢,其中包含相當多的數據:http://www.sqlfiddle.com/#!1/dfe4f/2 – hgolov

+0

謝謝,這非常完美。我感謝你一直到最後,併發送有用的鏈接。有一件事:8.4文檔也有在其中的查詢:看到這裏:http://www.postgresql.org/docs/8.4/static/queries-with.html。 – hgolov