繁体   English   中英

SQL:选择具有最大值的行并按单列分组

[英]SQL: Select row with max value and group by a single column

第一次在 stackoverflow 上提问,如有错误请见谅。

我正在尝试将旧表格转换为新格式。

旧表/输入示例:

| id                               | collectionId                     | infoText   |
|----------------------------------|----------------------------------|------------|
| 20200227112631476162094432822589 | 20200227112630931296846572143651 | Step 0     |
| 20200227112631512664092998338570 | 20200227112630931296846572143651 | Step 1     |
| 20200227112631652576662844108316 | 20200227112630931296846572143651 | Successful |

新表/输出:

| collectionId                     | startTimestamp                  | stopTimeStamp                   | lastStatus |
|----------------------------------|---------------------------------|---------------------------------|-------------|
| 20200227112630931296846572143651 | 27-FEB-20 11.26.30.931000000 AM | 27-FEB-20 11.26.50.911000000 AM | Successful  |

基本上需要以下内容:

  • 根据集合中最新行的信息创建一行:
    • 具有最大 id 和相同集合 id 的行。
  • 将集合 id 中的前 17 个字符转换为开始时间戳
    (例如: 2020022711263093 -> 27-FEB-20 11.26.30.931000000 AM)。
  • 将来自该集合的最新 id 的前 17 个字符转换为停止时间戳。 (例如: 2020022711263165 -> 27-FEB-20 11.26.50.911000000 AM)。

我一整天都在尝试这样做,我觉得我快要解决它了。 然而,我尝试的一切似乎都会导致不同的错误。

我最近的尝试:

CREATE table newTable AS

SELECT
    a.collectionId                                                                AS collectionId,
    a.id                                                                          AS id,
    to_timestamp(substr(a.collectionId , 0, 17), 'YYYYMMDDHH24MISSFF')            AS starttimestamp,
    "STOPTIMESTAMP"                                                               AS stoptimestamp,
    a.infoText                                                                    AS lastStatus,
FROM
    oldTable a
    INNER JOIN (
        SELECT
            MAX(id),
            to_timestamp(substr(MAX(id), 0, 17), 'YYYYMMDDHH24MISSFF')            AS stoptimestamp,
            collectionId                                                          AS collectionId
        FROM
            oldTable
        GROUP BY
            collectionId
    ) b ON a.collectionId = b.collectionId
           AND stoptimestamp = b.stoptimestamp;

然而,这会导致表具有重复的集合 ID。

我真的很感激您的帮助,因为我对 SQL 没有经验。 此处显示的示例被修改为更简单,我正在使用的表具有更多(额外文本)字段并包含超过 200 万行。 如果有帮助,它是一个 Oracle XE 18c DB。

谢谢您的帮助!

您可以使用窗口函数来标识每组的最后一条记录,然后进行日期转换:

select
    collection_id,
    to_timestamp(substr(collection_id, 1, 17), 'yyyymmddhh24missff') start_timestamp,
    to_timestamp(substr(id,            1, 17), 'yyyymmddhh24missff') end_timestamp,
    info_text last_status
from (
    select 
        t.*,
        row_number() over(partition by collection_id order by id desc) rn
    from mytable t
) t
where rn = 1

DB Fiddle 上的演示

COLLECTION_ID | START_TIMESTAMP              | END_TIMESTAMP                | LAST_STATUS
-------------------------------: | :--------------------------- | :--------------------------- | :----------
20200227112630931296846572143651 | 27-FEB-20 11.26.30.931000000 | 27-FEB-20 11.26.31.652000000 | Successful

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM