【问题标题】:A SQL query to get the last status for a file uploaded possibly using a sub query一个 SQL 查询,用于获取可能使用子查询上传的文件的最后状态
【发布时间】:2020-10-09 15:32:07
【问题描述】:

我需要编写一个查询,我认为其中需要一个子查询。目前,我正在使用 DataGrip 将查询编写为原始 SQL 语句,并且需要在 postGres 服务器上工作。我正在使用 Laravel 编写这个查询需要在其中工作的应用程序。

编写查询所需的两个表是 media_filesstatuses。两个表之间有一个链接: media_files.id = statuses.model_id

文件存储在media_files中,可以有pendingattached两种状态。文件的状态存储在状态statuses 表还可以包含其他事物的状态,例如任务、事件、用户等。

我需要一种方法来获取最后状态为 pending 的所有文件。有些文件甚至可能没有 pending 状态,可以忽略这些文件。

状态表可以保存同一个媒体文件的多个状态。因此,例如,您可以:

记录 1

media_files.id = 1

media_files.name = '简历文件'

statuses.id = 2

statuses.model_id = 1

statuses.model_type = 'App\MediaFile'

statuses.name = 'attached'

statuses.created_at = '2020-06-16 17:39:08'

记录 2

media_files.id = 1

media_files.name = '简历文件'

statuses.id = 1

statuses.model_id = 1

statuses.model_type = 'App\MediaFile'

statuses.name = '待定'

statuses.created_at = '2020-06-14 17:30:00'

我已开始查询,但它似乎无法正常工作:

select media_files.*, (
    select name
    from statuses
    where model_id = media_files.id
      and model_type = 'App\File'
    order by statuses.created_at desc
    limit 1
)
as latest_status
from media_files
inner join statuses on statuses.model_id = media_files.id
where statuses.model_type = 'App\Entities\Media\File'
order by media_files.id desc;

【问题讨论】:

    标签: mysql sql laravel postgresql subquery


    【解决方案1】:

    您可以使用条件聚合来确定最后一个未决状态是否是最后一个状态:

    select mf.*
    from media_files mf join
         (select s.model_id,
                 max(case when s.status = 'pending' then s.created_at end) as last_pending_created_at,
                 max(s.created_at) as last_created_at
          from statuses s
          group by s.model_id          
         ) s
         on s.model_id = mf.id
    where last_pending_created_at = last_created_at;
    

    您还可以使用相关子查询:

    select mf.*
    from (select mf.*,
                 (select s.status
                  from statuses s
                  where s.model_id = mf.id
                  order by s.created_at desc
                  limit 1
                 ) as last_status
          from media_files mf
         ) mf
    where last_status = 'pending';
    

    【讨论】:

    • 戈登,太棒了。我真的很感谢你的帮助。第一个查询运行得更快,所以我将使用那个。然而,尽管它几乎就在那里,但它并没有完全按照我的意愿工作。在某些情况下,同一文件的 statuses 表中可能有两条记录,并且 created_at 列的值可能完全相同 - 唯一的区别是实际状态一个是“待定”,另一个是“附加”-在这种情况下,有没有办法按 id 列值排序,因为我在 id 上使用自动增量 列。
    • @Riz 。 . .如果id 列确实捕获了排序,请使用它而不是created_at
    【解决方案2】:

    你也可以使用分析函数

    SELECT MEDIA_FILES.*,LATEST_STATUS.* 
    FROM 
    (SELECT NAME,MODEL_ID,
    MAX(CREATED_AT) OVER(PARTITION BY NAME) AS MAX_TM
    WHERE MODEL_ID = MEDIA_FILES.ID
    AND MODEL_TYPE = 'App\File') AS LATEST_STATUS,MEDIA_FILES
    WHERE LATEST_STATUS.MODEL_ID=MEDIA_FILES.MODEL_ID
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-10-25
      • 1970-01-01
      • 2020-03-07
      • 2019-02-25
      • 1970-01-01
      • 2011-08-12
      相关资源
      最近更新 更多