2017-05-04 74 views
0

與此查詢:POSTGRESQL:如何選擇每個組的第一行?

WITH responsesNew AS 
(
    SELECT DISTINCT responses."studentId", notation, responses."givenHeart", 
    SUM(notation + responses."givenHeart") OVER (partition BY responses."studentId" 
    ORDER BY responses."createdAt") AS total, responses."createdAt", 
    FROM responses 
) 
SELECT responsesNew."studentId", notation, responsesNew."givenHeart", total, 
responsesNew."createdAt" 
FROM responsesNew 
WHERE total = 3 
GROUP BY responsesNew."studentId", notation, responsesNew."givenHeart", total, 
responsesNew."createdAt" 
ORDER BY responsesNew."studentId" ASC 

我得到這個數據表:

studentId | notation | givenHeart | total |  createdAt  | 
----------+----------+------------+-------+--------------------+ 
374  | 1  | 0   | 3  | 2017-02-13 12:43:03 
374  | null  | 0   | 3  | 2017-02-15 22:22:17 
639  | 1  | 2   | 3  | 2017-04-03 17:21:30 
790  | 1  | 0   | 3  | 2017-02-12 21:12:23 
... 

我的目標是隻在我的數據表,以保持各組的初排如下所示:

studentId | notation | givenHeart | total |  createdAt  | 
----------+----------+------------+-------+--------------------+ 
374  | 1  | 0   | 3  | 2017-02-13 12:43:03 
639  | 1  | 2   | 3  | 2017-04-03 17:21:30 
790  | 1  | 0   | 3  | 2017-02-12 21:12:23 
... 

我該如何到達那裏?

我讀過許多問題在這裏,但沒有我曾與嘗試DISTINCTDISTINCT ON,在WHERELIMIT,等我工作過(當然,由於我缺乏瞭解)子查詢。我遇到了與窗口函數有關的錯誤,缺少ORDER BY中的列和其他一些我不記得的列。

+0

使用窗函數在with語句被它'ROW_NUMBER()以上(分區由studentID爲了通過createdAt)添加ROW_NUMBER和過濾RN'然後添加其中RN = 1到您的查詢。 – xQbert

回答

0

你可以用distinct on來做到這一點。該查詢將如下所示:

WITH responsesNew AS (
     SELECT DISTINCT r."studentId", notation, r."givenHeart", 
      SUM(notation + r."givenHeart") OVER (partition BY r."studentId" 
                ORDER BY r."createdAt") AS total, 
      r."createdAt" 
     FROM responses r 
    ) 
SELECT DISTINCT ON (r."studentId") r."studentId", notation, r."givenHeart", total, 
r."createdAt" 
FROM responsesNew r 
WHERE total = 3 
ORDER BY r."studentId" ASC, r."createdAt"; 

我很確定這可以簡化。我只是不明白CTE的目的。以這種方式使用SELECT DISTINCT非常好奇。

如果您想要簡化查詢,請詢問另一個問題與樣品數據,所需結果和您正在做什麼的解釋,幷包括查詢或此問題的鏈接。

+0

謝謝你的回答,這工作得很好!我稍後可能會問另一個問題,並將採樣數據附加到它上面,但我首先需要根據我的理解來清除此步驟,並看看我是否可以單獨使用此數據庫中的度量標準。再次感謝 :) – DFATPUNK

0

使用ROW_NUMBER()窗函數的行號添加到每個分區,然後只顯示1行中

沒有必要,如果只有一個表涉及到完全限定的名字。並在符合條件時使用別名來簡化可讀性。

WITH responsesNew AS 
(
    SELECT "studentId" 
     , notation 
     , "givenHeart" 
     , SUM(notation + "givenHeart") OVER (partition BY "studentId" ORDER BY "createdAt") AS total 
     , "createdAt" 
     , Row_number() OVER ("studentId" ORDER BY "createdAt") As RNum 
    FROM responses r 
) 
SELECT RN."studentId" 
    , notation, RN."givenHeart" 
    , total 
    , RN."createdAt" 
FROM responsesNew RN 
WHERE total = 3 
    AND RNum = 1 
GROUP BY RN."studentId" 
     , notation 
     , RN."givenHeart", total 
     , RN."createdAt" 
ORDER BY RN."studentId" ASC