oracle SQL:如何检索一对多关系中最近的关联

gzszwxb4  于 2023-06-22  发布在  Oracle
关注(0)|答案(2)|浏览(146)

下表存储了一对多关系,其中一个用户可能与一个或多个配置文件相关联:

+----+---------+------------+------------------------+
| ID | USER_ID | PROFILE_ID | LAST_PROFILE_DATE_TIME |
+----+---------+------------+------------------------+
|  1 |     100 |        101 | 04.06.23 08:35:19.5393 |
|  2 |     100 |        102 | 05.06.23 08:35:19.5393 |
+----+---------+------------+------------------------+

如何获取用户100的最新配置文件?下面是预期的结果:

+------------+
| PROFILE_ID |
+------------+
|        102 |
+------------+

我需要一个单一的值来更新另一个表中的字段。
这是我的尝试。。但问题是我得到了两行,因为GROUP BY子句需要除了MAX之外的所有字段:

SELECT up.PROFILE_ID
FROM
  (SELECT USER_ID, PROFILE_ID, MAX(LAST_PROFILE_DATE_TIME)
     FROM USER_PROFILE
    GROUP BY USER_ID, PROFILE_ID) up
WHERE up.USER_ID = 100;

我需要在Oracle和PostgreSQL上运行查询。任何帮助都将不胜感激。

vnjpjtjt

vnjpjtjt1#

您可以按以下方式执行此操作:
首先获取每个USER_ID的最新LAST_PROFILE_DATE_TIME:

select USER_ID, max(LAST_PROFILE_DATE_TIME) as MAX_LAST_PROFILE_DATE_TIME
  from USER_PROFILE
  where USER_ID = 100
  group by USER_ID

然后将此数据集连接到表以获取PROFILE_ID:

select t.PROFILE_ID
from USER_PROFILE t
inner join (
  select USER_ID, max(LAST_PROFILE_DATE_TIME) as MAX_LAST_PROFILE_DATE_TIME
  from USER_PROFILE
  where USER_ID = 100
  group by USER_ID
) as s on s.USER_ID = t.USER_ID and s.MAX_LAST_PROFILE_DATE_TIME = t.LAST_PROFILE_DATE_TIME;
knpiaxh1

knpiaxh12#

你可以使用ROW_NUMBER解析函数:

SELECT profile_id,
       last_profile_date_time
FROM   (
  SELECT profile_id,
         last_profile_date_time,
         ROW_NUMBER()
           OVER (ORDER BY last_profile_date_time DESC) AS rn
  FROM   table_name
  WHERE  user_id = 100
  ORDER BY last_profile_date_time DESC
) q
WHERE  RN = 1;

或者两个数据库都支持FETCH FIRST ROW ONLY语法:

SELECT profile_id,
       last_profile_date_time
FROM   table_name
WHERE  user_id = 100
ORDER BY last_profile_date_time DESC
FETCH FIRST ROW ONLY;

其中,对于样本数据:

CREATE TABLE table_name (
  ID         INT,
  USER_ID    INT,
  PROFILE_ID INT,
  LAST_PROFILE_DATE_TIME TIMESTAMP
);

INSERT INTO table_name (id, user_id, profile_id, last_profile_date_time)
  VALUES (1, 100, 101, TIMESTAMP '2023-06-04 08:35:19.5393' );
INSERT INTO table_name (id, user_id, profile_id, last_profile_date_time)
  VALUES (2, 100, 102, TIMESTAMP '2023-06-05 08:35:19.5393' );

两个输出:
| 配置文件ID| last_profile_date_time|
| - -----|- -----|
| 一百零二|2023-06-05 08:35:19.5393|
PostgreSQL fiddleOracle fiddle

相关问题