在ID

时间:2017-06-22 20:19:18

标签: sql spring oracle greatest-n-per-group

鉴于TASK_ID,检索每个文件的最新版本的最有效方法是什么?

以下是我正在使用的示例表。

ID    TASK_ID    FILENAME    VERSION_NUMBER    RANDOM_COLUMN
1     1          a.txt       1                 112
2     1          b.txt       1                 231231
3     1          c.txt       1                 234356
4     1          a.txt       2                 35
5     1          b.txt       2                 84
6     1          b.txt       3                 97604
7     2          aa.txt      1                 6956
8     2          bb.txt      1                 9760054

这是我到目前为止所做的。

SELECT FILENAME, TASK_ID, MAX(VERSION_NUMBER)
FROM TABLE_NAME
GROUP BY FILENAME, TASK_ID
HAVING TASK_ID = '1';

不幸的是,上面只给出了我在SELECT语句中的3列而不是整行,并且添加更多列会给我一个错误。

FILENAME    TASK_ID    MAX(VERSION_NUMBER)
a.txt       1          2
b.txt       1          3
c.txt       1          1

我怎样才能获得整行?

我计划将此SQL查询添加到Spring Repository中的Query注释,并将其作为本机查询运行。这是最好的方法吗?

修改 我最终得到了这个SQL查询,它得到了我想要的,但我不确定这是正确的还是有效的。

SELECT ta.*
FROM TABLE_NAME ta
INNER JOIN (SELECT FILENAME, TASK_ID, MAX(VERSION_NUMBER) vn
  FROM TABLE_NAME
  GROUP BY FILENAME, TASK_ID
  HAVING TASK_ID = '1') sq
ON ta.FILENAME = sq.FILENAME
AND ta.TASK_ID = sq.TASK_ID
AND ta.VERSION_NUMBER = sq.vn;

上述SQL查询的结果

ID    TASK_ID    FILENAME    VERSION_NUMBER    RANDOM_COLUMN
3     1          c.txt       1                 234356
4     1          a.txt       2                 35
6     1          b.txt       3                 97604

2 个答案:

答案 0 :(得分:0)

使用row_number()

SELECT ta.*
FROM (SELECT ta.*,
             ROW_NUMBER() OVER (PARTITION BY FILENAME, TASK_ID ORDER BY VERSION_NUMBER DESC) as seqnum
      FROM TASK_ARTIFACT ta
     ) ta
WHERE seqnum = 1;

答案 1 :(得分:0)

是的,它是正确的,并且没有看到您当前的方法(编辑过的)有任何问题。我也会这样做。除此之外,HAVING中的条件应与WHERE类似

SELECT ta.*
FROM TABLE_NAME ta
INNER JOIN (SELECT FILENAME, TASK_ID, MAX(VERSION_NUMBER) vn
  FROM TABLE_NAME
  WHERE TASK_ID = '1'
  GROUP BY FILENAME, TASK_ID
  ) sq
ON ta.FILENAME = sq.FILENAME
AND ta.TASK_ID = sq.TASK_ID
AND ta.VERSION_NUMBER = sq.vn;