【问题标题】:join second table and select latest entry per timestamp加入第二个表并选择每个时间戳的最新条目
【发布时间】:2021-02-24 16:06:24
【问题描述】:

我想创建一个模式匹配的搜索查询,在给定关键字的情况下最多返回 10 个用户。它从两个表中获取数据:“用户”和“上传”。

'uploads' 包含所有用户上传或没有条目。对于每个找到的与关键字匹配的用户,我需要每个时间戳的最新条目,如果不存在,我需要该列的 null。

我的问题是我想不出一种方法来为用户选择最新的上传条目 (如果不存在条目,则将 null 作为列值)。

http://sqlfiddle.com/#!17/767bb/3

CREATE TABLE users (
  "user_uuid" uuid NOT NULL,
  "username" varchar(25)
);

CREATE TABLE uploads (
  "file_uuid" uuid NOT NULL,
  "user_uuid" uuid NOT NULL,
  "timestamp" timestamptz(6) DEFAULT now()
);

insert into uploads(file_uuid, user_uuid) values 
-- user1                                  
('aaa3d0d1-a403-4af9-ba9e-c1df8fcb6952', '0123d0d1-a403-4af9-ba9e-c1df8fcb6952'),
('bbb3d0d1-a403-4af9-ba9e-c1df8fcb6952', '0123d0d1-a403-4af9-ba9e-c1df8fcb6952'),
-- user2
('ccc3d0d1-a403-4af9-ba9e-c1df8fcb6952', '1123d0d1-a403-4af9-ba9e-c1df8fcb6952'),
('ddd3d0d1-a403-4af9-ba9e-c1df8fcb6952', '1123d0d1-a403-4af9-ba9e-c1df8fcb6952')
-- user 3 has no uploads
;


insert into users 
  (user_uuid, username) 
VALUES 
  ('0123d0d1-a403-4af9-ba9e-c1df8fcb6952', 'user1'),
  ('1123d0d1-a403-4af9-ba9e-c1df8fcb6952', 'user2'),
  ('2123d0d1-a403-4af9-ba9e-c1df8fcb6952', 'user3');

我尝试了什么:

-- this query returns only one row
select
  us.username,
  us.user_uuid,
  up.file_uuid as cover,
  up.timestamp
 from users us
 right join (
   select file_uuid, user_uuid, timestamp
   from uploads
   order by timestamp
   limit 1
 ) up on us.user_uuid = up.user_uuid
 WHERE
    us.username ILIKE '%user%'
LIMIT 10;

我的期望

username    user_uuid   cover   timestamp

user1   0123d0d1-a403-4af9-ba9e-c1df8fcb6952    aaa3d0d1-a403-4af9-ba9e-c1df8fcb6952    2021-02-24T15:57:51.199186Z
user2   1123d0d1-a403-4af9-ba9e-c1df8fcb6952    ddd3d0d1-a403-4af9-ba9e-c1df8fcb6952    2021-02-24T15:57:51.199186Z
user3   2123d0d1-a403-4af9-ba9e-c1df8fcb6952    null    2021-02-24T15:57:51.199186Z

【问题讨论】:

  • 样本数据和期望的结果在问题中将阐明您想要做什么。目前还不清楚小提琴中的查询与该问题有什么关系。

标签: sql postgresql


【解决方案1】:

你可以使用distinct on:

select distinct on (us.user_uuid) us.* ul.*
from users us left join
     uploads ul
     us.user_uuid = ul.user_uuid
where us.username ilike '%user%'
order by us.user_uuid, ul.timestamp desc;

【讨论】:

    【解决方案2】:

    试试这个:

     select
      us.username,
      us.user_uuid,
      up.file_uuid as cover,
      up.timestamp
     from users us
     left join uploads up on us.user_uuid = up.user_uuid
     left join (
        select user_uuid, max(timestamp) max_time
        from uploads
        group by user_uuid
     ) m ON m.user_uuid = up.user_uuid and max_time=up.timestamp
     WHERE
        us.username LIKE '%user%'
    LIMIT 10;
    

    使用您的数据,它会返回

    user1   0123d0d1-a403-4af9-ba9e-c1df8fcb6952    aaa3d0d1-a403-4af9-ba9e-c1df8fcb6952    2021-02-24 16:34:35
    user1   0123d0d1-a403-4af9-ba9e-c1df8fcb6952    bbb3d0d1-a403-4af9-ba9e-c1df8fcb6952    2021-02-24 16:34:35
    user2   1123d0d1-a403-4af9-ba9e-c1df8fcb6952    ccc3d0d1-a403-4af9-ba9e-c1df8fcb6952    2021-02-24 16:34:35
    user2   1123d0d1-a403-4af9-ba9e-c1df8fcb6952    ddd3d0d1-a403-4af9-ba9e-c1df8fcb6952    2021-02-24 16:34:35
    user3   2123d0d1-a403-4af9-ba9e-c1df8fcb6952        
    

    因为每次上传都有相同的时间戳

    【讨论】:

      猜你喜欢
      • 2012-08-07
      • 1970-01-01
      • 2016-05-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多