Postgresql

使用 max() 的情況

  • May 19, 2016

我知道如何在 SQL Server 中執行此操作,但 Postgres 不同。

我想退還最高員工工資。

Select b.enumber, b.bday, 
case when Max(c.id) then c.pay
ELSE c.pay
End As "Current Pay"
From employee b
inner join humanr c
on b.empid = c.empid

這會產生一個錯誤:

錯誤:CASE/WHEN 的參數必須是布爾類型,而不是整數類型

我怎樣才能從那裡退回工資max(id)

humanr資料結構為idemployeeiddatepay。此表將包含每位員工的小時工資,基於employeeid. 對於employee表中的每個員工,我想從那裡退還工資,MAX(id)以便為員工退還目前工資。

例子:

1  1234  01/01/2016  8.00
2  1234  04/04/2016  10.00
3  5555  05/01/2016  12.00
4  1234  05/16/2016  10.50

所以對於5555我想要12.00返回,對於1234我想要10.50

有很多方法可以做到這一點。許多都可以在 SQL Server 和 Postgres 中工作,例如使用以下ROW_NUMBER()函式:

WITH cte AS
( SELECT e.enumber, e.bday, c.empid, c.pay,
        ROW_NUMBER() OVER (PARTITION BY c.empid 
                           ORDER BY c.id DESC)
          AS rn
 FROM employee AS e
   INNER JOIN humanr AS c
     ON e.empid = c.empid
) 
SELECT enumber, bday, empid, pay AS current_pay
FROM cte
WHERE rn = 1 ;

順便說一句,如果你想要最新的工資,為什麼ORDER BY id DESC應該使用而不是ORDER BY c.date DESC?這會更有意義。


另一種專有的 Postgres 方法是使用DISTINCT ON

SELECT DISTINCT ON (c.empid)
   e.enumber, e.bday, c.empid
   c.pay AS current_pay
FROM employee AS e
 INNER JOIN humanr AS c
   ON e.empid = c.empid
ORDER BY c.empid, c.id DESC ;

另一種需要最新版本(9.3+)的通常更有效的方法是使用LATERAL語法(類似於CROSS/OUTER APPLYSQL Server):

SELECT e.enumber, e.bday, e.empid
      c.pay AS current_pay
FROM employee AS e
 CROSS JOIN LATERAL 
   ( SELECT ci.*
     FROM humanr AS ci
     WHERE e.empid = ci.empid
     ORDER BY ci.id DESC
     LIMIT 1
   ) AS c ;

哪種技術更有效取決於數據分佈。請參閱此基準

引用自:https://dba.stackexchange.com/questions/138915