在 postgresql12 上使用 join 查询每个的最后一个值

query last value from each with join on postgresql12

我正在构建一个查询,但我最近意识到我有多个值,但我只需要最后一个

它是 2 个表的结果,我有 2 个 2200339 和 2 个 catcode,旧的和新的。 我该如何过滤它?

"id"     "typecode" "catcode"   "sampledatetime"            "somevalue"
"2200338"   6       "3101"      "2020-03-02 07:17:54.047"   0.02000
"2200338"   7       "3101"      "2020-03-02 07:17:54.067"   0.02000
"2200338"   8       "3101"      "2020-03-02 07:17:54.087"   0.02500
"2200338"   9       "3101"      "2020-03-02 07:17:55.007"   0.06000
"2200338"   10      "3101"      "2020-03-02 07:17:55.021"   0.06000
"2200339"   6       "9603"      "2020-03-02 07:57:11.068"   0.01500
"2200339"   7       "9603"      "2020-03-02 07:57:11.091"   0.01500
"2200339"   8       "9603"      "2020-03-02 07:57:12.009"   0.02500
"2200339"   9       "9603"      "2020-03-02 07:57:12.028"   0.06000
"2200339"   10      "9603"      "2020-03-02 07:57:12.039"   0.06000
"2200339"   6       "4712"      "2020-03-04 15:09:43.061"   0.02000
"2200339"   7       "4712"      "2020-03-04 15:09:43.064"   0.02000
"2200339"   8       "4712"      "2020-03-04 15:09:43.067"   0.02500
"2200339"   9       "4712"      "2020-03-04 15:09:43.072"   0.06000
"2200339"   10      "4712"      "2020-03-04 15:09:43.075"   0.06000

但我只需要这个:

"id"     "typecode" "catcode"   "sampledatetime"            "somevalue"
"2200338"   6       "3101"      "2020-03-02 07:17:54.047"   0.02000
"2200338"   7       "3101"      "2020-03-02 07:17:54.067"   0.02000
"2200338"   8       "3101"      "2020-03-02 07:17:54.087"   0.02500
"2200338"   9       "3101"      "2020-03-02 07:17:55.007"   0.06000
"2200338"   10      "3101"      "2020-03-02 07:17:55.021"   0.06000
"2200339"   6       "4712"      "2020-03-04 15:09:43.061"   0.02000
"2200339"   7       "4712"      "2020-03-04 15:09:43.064"   0.02000
"2200339"   8       "4712"      "2020-03-04 15:09:43.067"   0.02500
"2200339"   9       "4712"      "2020-03-04 15:09:43.072"   0.06000
"2200339"   10      "4712"      "2020-03-04 15:09:43.075"   0.06000

查询:

SELECT ranalysis.id,
    ranalysis.typecode,
    ranalysis.catcode,
    ranalysis.sampledatetime
    rchemistry.somevalue1,    rchemistry.somevalue2,    rchemistry.somevalue3,.......
   FROM ranalysis
     JOIN rchemistry ON ranalysis.oid = rchemistry.oid AND ranalysis.typecode >= 6 AND ranalysis.typecode <= 10
  ORDER BY ranalysis.oid;

提前致谢

使用distinct on:

SELECT DISTINCT ON (ra.id, ra.typecode) ra.*,
       rc.somevalue1, rc.somevalue2, . . .
FROM ranalysis ra JOIN
     rchemistry rc
     ON ra.oid = rc.oid AND ra.typecode >= 6 AND ra.typecode <= 10
ORDER BY ra.id, ra.typecode, ra.sampledatetime DESC;

我简化了 SELECT 以专注于查询的重要部分。 DISTINCT ON 是一个(方便的)Postgres 扩展,returns 每个“组”一个值;该组由 DISTINCT ON 定义。哪一行由ORDER BY.

中分组列后面的键决定

一种方法是 ORDER BY ranalysis.oid DESC(颠倒查询顺序)和 LIMIT 1.

请注意,这很可能不是最快的方法。但它确实解决了问题。

WITH
-- your input
input(id,typecode,catcode,sampledatetime,somevalue) AS (
          SELECT 2200338, 6,3101,TIMESTAMP '2020-03-02 07:17:54.047',0.02000
UNION ALL SELECT 2200338, 7,3101,TIMESTAMP '2020-03-02 07:17:54.067',0.02000
UNION ALL SELECT 2200338, 8,3101,TIMESTAMP '2020-03-02 07:17:54.087',0.02500
UNION ALL SELECT 2200338, 9,3101,TIMESTAMP '2020-03-02 07:17:55.007',0.06000
UNION ALL SELECT 2200338,10,3101,TIMESTAMP '2020-03-02 07:17:55.021',0.06000
UNION ALL SELECT 2200339, 6,9603,TIMESTAMP '2020-03-02 07:57:11.068',0.01500
UNION ALL SELECT 2200339, 7,9603,TIMESTAMP '2020-03-02 07:57:11.091',0.01500
UNION ALL SELECT 2200339, 8,9603,TIMESTAMP '2020-03-02 07:57:12.009',0.02500
UNION ALL SELECT 2200339, 9,9603,TIMESTAMP '2020-03-02 07:57:12.028',0.06000
UNION ALL SELECT 2200339,10,9603,TIMESTAMP '2020-03-02 07:57:12.039',0.06000
UNION ALL SELECT 2200339, 6,4712,TIMESTAMP '2020-03-04 15:09:43.061',0.02000
UNION ALL SELECT 2200339, 7,4712,TIMESTAMP '2020-03-04 15:09:43.064',0.02000
UNION ALL SELECT 2200339, 8,4712,TIMESTAMP '2020-03-04 15:09:43.067',0.02500
UNION ALL SELECT 2200339, 9,4712,TIMESTAMP '2020-03-04 15:09:43.072',0.06000
UNION ALL SELECT 2200339,10,4712,TIMESTAMP '2020-03-04 15:09:43.075',0.06000
)
,
-- timestamps between catcodes not overlapping
-- so min timestamp per id/catcode combination
-- is good for choosing
relevant_groups AS (
  SELECT
    id
  , catcode
  , MIN(sampledatetime) AS sampledatetime
  FROM input 
  GROUP BY
    id
  , catcode
)
,
-- now, need newest sampledatetime per id/catcode
-- combination. OLAP func with ROW_NUMBER() descending
with_filter_val AS (
  SELECT
    id
  , catcode
  , ROW_NUMBER() OVER(PARTITION BY id ORDER BY sampledatetime DESC) AS rn
  FROM relevant_groups
)
-- finally , join the last Common Table Expression back to input
-- filtering by the obtained row number  = 1 - and re-ordering
SELECT
  i.*
FROM with_filter_val
JOIN input i USING(id,catcode)
WHERE rn=1
ORDER BY id,sampledatetime;
-- out    id    | typecode | catcode |     sampledatetime      | somevalue 
-- out ---------+----------+---------+-------------------------+-----------
-- out  2200338 |        6 |    3101 | 2020-03-02 07:17:54.047 |   0.02000
-- out  2200338 |        7 |    3101 | 2020-03-02 07:17:54.067 |   0.02000
-- out  2200338 |        8 |    3101 | 2020-03-02 07:17:54.087 |   0.02500
-- out  2200338 |        9 |    3101 | 2020-03-02 07:17:55.007 |   0.06000
-- out  2200338 |       10 |    3101 | 2020-03-02 07:17:55.021 |   0.06000
-- out  2200339 |        6 |    4712 | 2020-03-04 15:09:43.061 |   0.02000
-- out  2200339 |        7 |    4712 | 2020-03-04 15:09:43.064 |   0.02000
-- out  2200339 |        8 |    4712 | 2020-03-04 15:09:43.067 |   0.02500
-- out  2200339 |        9 |    4712 | 2020-03-04 15:09:43.072 |   0.06000
-- out  2200339 |       10 |    4712 | 2020-03-04 15:09:43.075 |   0.06000