2017-05-04 142 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 
相关问题