簡體   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