2015-10-13 61 views
1

我有下面的表:更新基於其他列的列在PostgreSQL

id integer 
sumqty numeric 
maxqty numeric 

id, sumqty是由其他功能定期更新的列。 我需要編寫一個傳遞這兩列的函數並更新maxqty列。

例如:功能運行後

id, sumqty, maxqty 
5 20 
5 70 
5 45 
3 20 
1 12 
1 2.5 

,所需的輸出將是:

id, sumqty, maxqty 
5 20  45 
5 10  45 
5 45  45 
3 20  20 
1 12  12 
1 2.5  12 

我寫了這個代碼:

update A set maxqty= (select MAX(sumqty) OVER (PARTITION BY id)) 

,但它並不總是有效。有時它不會給我真正的MAX。

我的代碼有什麼問題?

+1

創建一個視圖,而不是和你永遠不會有不一致的數據。 (或者使用觸發器。)存儲計算數據通常是一個糟糕的主意(來自其他列)。 – jarlh

+0

好,但仍然如此,爲什麼它不會像預期的那樣產生MAX? – SMW

回答

1

使用相關子查詢來代替:

SqlFiddleDemo

UPDATE mytable t1 
SET maxqty= (SELECT MAX(sumqty) 
      FROM mytable t2 
      WHERE t1.id = t2.id); 

結果:

╔═════╦═════════╦════════╗ 
║ id ║ sumqty ║ maxqty ║ 
╠═════╬═════════╬════════╣ 
║ 5 ║ 20  ║  45 ║ 
║ 5 ║ 10  ║  45 ║ 
║ 5 ║ 45  ║  45 ║ 
║ 3 ║ 20  ║  20 ║ 
║ 1 ║ 12  ║  12 ║ 
║ 1 ║ 2.5  ║  12 ║ 
╚═════╩═════════╩════════╝ 

更有效的方式:

WITH cte AS 
( 
    SELECT id, MAX(sumqty) AS sumqty 
    FROM mytable 
    GROUP BY id 
) 
UPDATE mytable m 
SET maxqty = c.sumqty 
FROM cte c 
WHERE m.id = c.id; 

原始查詢:

update mytable 
set maxqty= (select MAX(sumqty) OVER (PARTITION BY id); 

給出:

╔═════╦═════════╦════════╗ 
║ id ║ sumqty ║ maxqty ║ 
╠═════╬═════════╬════════╣ 
║ 5 ║ 20  ║ 20  ║ 
║ 5 ║ 10  ║ 10  ║ 
║ 5 ║ 45  ║ 45  ║ 
║ 3 ║ 20  ║ 20  ║ 
║ 1 ║ 12  ║ 12  ║ 
║ 1 ║ 2.5  ║ 2.5 ║ 
╚═════╩═════════╩════════╝ 

這是每行,因爲UPDATE作品。而且你的子查詢只有一行來處理它們。

+0

不是PARTITION BY ID應該給出該ID的所有行? – SMW

+0

@SMW把它想成UPDATE mytable SET maxqty =(SELECT MAX(sumqty)OVER(PARTITION BY id)FROM(SELECT id,sumqty,...)AS sub);'。你只有一行來處理。 – lad2025

+0

是的但是:SELECT MAX(sumqty)OVER(PARTITION BY id應傳遞該ID的所有行 – SMW

0
update mytable 
set maxqty=t.max 
    from (select id,max(sumqty) from mytable group by id) t 
where t.id=mytable.id 

SQLFIDDLE