【问题标题】:如何在 Oracle 中与 Group By 和 Order By 一起使用? [复制]
【发布时间】:2021-11-30 20:45:07
【问题描述】:
SELCT * FROM MyTable;

ID    Status            posted_date       posted_by
---------------------------------------------------
0      invalid          01/01/2021         abc
1      in-progress      02/01/2021         xyz
0      invalid          03/01/2021         lmn
2      complete         04/01/2021         pqr
1      in-progress      05/01/2021         newton
2      complete         06/01/2021         einstein
2      complete         07/01/2021         jack

我需要按 ID 分组。 然后按posted_date 降序排列。 然后找出发布最新交易的用户。

在这种情况下,我的预期输出是,

ID    Status            posted_date       posted_by
---------------------------------------------------
2      complete          07/01/2021        jack
1      in-progress       05/01/2021        newton
0      invalid           03/01/2021        lmn

以下是我尝试过的。我没有得到任何行。

SELECT COUNT(ID), ID, status, posted_by,posted_date
FROM MyTable
GROUP BY ID, status, posted_by,posted_date
HAVING COUNT(ID) > 1
ORDER BY posted_date DESC;

【问题讨论】:

  • 暂时跳过 HAVING 子句,仔细查看 GROUP BY 结果。

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


【解决方案1】:

你的问题是获取最大日期的行,你有几种方法来获取它

SELECT ID, status, posted_by, posted_date
FROM MyTable
WHERE (id, posted_date) IN 
    (
        SELECT id, MAX(posted_date)
        FROM MyTable
        GROUP BY id
    )
ORDER BY id;

使用连接

SELECT t.ID, t.status, t.posted_by, t.posted_date
FROM MyTable t
INNER JOIN 
(
    SELECT id, MAX(posted_date) AS max_posted_date
    FROM MyTable
    GROUP BY id
) m
ON t.id = m.id AND t.posted_date = m.max_posted_date
ORDER BY t.id;

或者使用解析函数

SELECT *
FROM 
(
    SELECT ID, status, posted_by, posted_date,
        ROW_NUMBER() OVER (PARTITION BY id ORDER by posted_date DESC) AS rn
    FROM MyTable
)
WHERE rn = 1 
ORDER BY id;

【讨论】:

    【解决方案2】:

    您似乎不想使用聚合函数。看起来您想使用窗口功能。像这样的东西(使用dense_rankrow_number 而不是rank,这取决于你想如何处理关系)

    with ranked_data as (
      select t.*,
             rank() over (partition by id 
                              order by posted_date desc) rnk
        from yourTable t
    )
    select *
      from ranked_data
     where rnk = 1
    

    【讨论】:

      【解决方案3】:

      架构和插入语句:

       create table MyTable(ID int, Status varchar(100), posted_date date, posted_by varchar(50));
      
       insert into MyTable values(0, 'invalid',          date'2021-01-01','abc');
       insert into MyTable values(1, 'in-progress',      date'2021-01-02','xyz');
       insert into MyTable values(0, 'invalid',          date'2021-01-03','lmn');
       insert into MyTable values(2, 'complete',         date'2021-01-04','pqr');
       insert into MyTable values(1, 'in-progress',      date'2021-01-05','newton');
       insert into MyTable values(2, 'complete' ,        date'2021-01-06','einstein');
       insert into MyTable values(2, 'complete',         date'2021-01-07','jack');
      

      查询:

       with cte as
       (
         select ID,Status,posted_date,posted_by,
         row_number()over(partition by id order by posted_date desc) as rn
         from MyTable
       )
       select ID,Status,posted_date,posted_by from cte where rn=1 
       order by posted_date desc
      

      输出:

      ID STATUS POSTED_DATE POSTED_BY
      2 complete 07-JAN-21 jack
      1 in-progress 05-JAN-21 newton
      0 invalid 03-JAN-21 lmn

      db小提琴here

      【讨论】:

        【解决方案4】:

        您也可以使用 keep dense_rank 聚合子句来做到这一点。

        select ID
        , max(STATUS)keep(dense_rank first order by POSTED_DATE desc) STATUS
        , max(POSTED_DATE)keep(dense_rank first order by POSTED_DATE desc)POSTED_DATE
        , max(POSTED_BY)keep(dense_rank first order by POSTED_DATE desc)POSTED_BY
        from myTable t
        group by ID
        order by ID desc
        ;
        

        demo

        【讨论】:

        • 你必须非常小心这个解决方案。如果一个 id 可以有 2 行具有相同的最新日期,那么您可以从一行获取状态,从另一行获取用户。 db<>fiddle
        猜你喜欢
        • 2012-04-19
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-03-09
        • 2014-08-31
        相关资源
        最近更新 更多