簡體   English   中英

具有案例/等級功能的LAG功能

[英]LAG fucntion With Case/Rank Function

我在單個表中的列lbb_diag_value中有兩條消息('usb_port_reset','onewire_cable')。

我使用的兩列是:created_at(帶有時間戳),lbb_diag_value

問題:我想將one_wire_cable與所有連續的usb_port_reset消息相關聯,直到在表中找到另一個one_wire_cable。

例如:

         Created_at    lbb_diag_value
         1 PM          onewire_cable
         1:15 PM       usb_port_reset
         3:00 Pm       usb_port_reset
         12Pm          onewire_cable
         Some Time     usb_port_reset

Cuurent解決方案:我正在使用滯后函數和左連接,如果我沒有連續的usb_port_reset消息,這可以正常工作。

以下是我的代碼:

  WITH CTE
AS (
    SELECT e2.identifier
        ,e2.created_at
        ,e2.model
        ,e2.sw_pkg_version
        ,e2.type
        ,e2.lbb_diag_value
        ,e2.lbb_diag_type
    FROM (
        SELECT e1.identifier
            ,e1.created_at
            ,e1.model
            ,e1.sw_pkg_version
            ,e1.lbb_diag_type
            ,e1.lbb_diag_value
            ,e1.type
        FROM eld_messages e1
        WHERE e1.type = 'lbb_diag'
            AND e1.lbb_diag_type = 'usb_port_reset'
            AND { % condition created_filter % } e1.created_at { % endcondition % }
        ) e2
    )
    ,onewire
AS (
    SELECT e2.identifier
        ,e2.lbb_diag_value
        ,e2.created_at
        ,e2.type
        ,e2.lbb_diag_type
        ,e2.prev_lbb_diag_type
        ,e2.prev_created_at
        ,e2.prev_lbb_diag_value
        ,e2.model
        ,e2.sw_pkg_version
        ,e2.seqnum
    FROM (
        SELECT e1.identifier
            ,e1.created_at
            ,e1.lbb_diag_value
            ,e1.type
            ,e1.lbb_diag_type
            ,e1.event_id
            ,e1.model
            ,e1.sw_pkg_version
            ,LAG(e1.lbb_diag_type) OVER (
                PARTITION BY e1.identifier ORDER BY e1.created_at
                    ,e1.event_id DESC
                ) AS prev_lbb_diag_type
            ,LAG(e1.created_at) OVER (
                PARTITION BY e1.identifier ORDER BY e1.created_at
                    ,e1.event_id DESC
                ) AS prev_created_at
            ,LAG(e1.lbb_diag_value) OVER (
                PARTITION BY e1.identifier ORDER BY e1.created_at
                    ,e1.event_id
                ) AS prev_lbb_diag_value
            ,row_number() OVER (
                PARTITION BY e1.lbb_diag_type ORDER BY e1.created_at
                    ,e1.event_id DESC
                ) seqnum
        FROM eld_messages e1
        WHERE e1.type = 'lbb_diag'
            AND e1.lbb_diag_type IN (
                'onewire_cable'
                ,'usb_port_reset'
                )
            AND { % condition created_filter % } e1.created_at { % endcondition % }
        ORDER BY e1.identifier
            ,e1.created_at
        ) e2
    WHERE (
            e2.lbb_diag_type = 'usb_port_reset'
            AND e2.prev_lbb_diag_type = 'onewire_cable'
            )
        OR (
            CASE 
                WHEN e2.lbb_diag_type = 'usb_port_reset'
                    AND e2.prev_lbb_diag_type = 'usb_port_reset'
                    THEN e2.seqnum = 1
                END
            )
    )
SELECT cte.identifier
    ,cte.created_at
    ,cte.model
    ,cte.sw_pkg_version
    ,cte.type
    ,cte.lbb_diag_type
    ,cte.lbb_diag_value
    ,onewire.prev_lbb_diag_value AS onewire_lbb_diag_value
    ,onewire.prev_created_at AS onewire_created_at
FROM cte
LEFT JOIN onewire ON cte.identifier = onewire.identifier
    AND cte.created_at = onewire.created_at; 

是否可以使用延遲嵌套子選擇並過濾掉lbb_diag_value沒有變化的記錄? 我沒有嘗試理解那個巨大查詢的整個上下文,如果你需要其他記錄,但是滯后可以是檢測邊界的好方法,看起來就像你需要的那樣。

FROM (
    SELECT * FROM (
        SELECT e1.identifier ,e1.created_at ,e1.lbb_diag_value ,e1.type ,e1.lbb_diag_type ,e1.event_id
            ,e1.model ,e1.sw_pkg_version
            ,LAG(e1.lbb_diag_type) OVER (PARTITION BY e1.identifier ORDER BY e1.created_at ,e1.event_id DESC) AS prev_lbb_diag_type
            ,LAG(e1.created_at) OVER ( PARTITION BY e1.identifier ORDER BY e1.created_at ,e1.event_id DESC) AS prev_created_at
            ,LAG(e1.lbb_diag_value) OVER ( PARTITION BY e1.identifier ORDER BY e1.created_at ,e1.event_id) AS prev_lbb_diag_value
            ,row_number() OVER (PARTITION BY e1.lbb_diag_type ORDER BY e1.created_at ,e1.event_id DESC) seqnum
        FROM eld_messages e1
        WHERE e1.type = 'lbb_diag' AND e1.lbb_diag_type IN ('onewire_cable' ,'usb_port_reset')
            AND { % condition created_filter % } e1.created_at { % endcondition % }
        ORDER BY e1.identifier, e1.created_at
    ) t
    WHERE lbb_diag_value != prev_lbb_diag_value
) e2

如果您需要所有記錄,您可以將其轉換為帶有連接的兩個子選擇(您已離開的選擇連接到檢測轉換的選擇),其中轉換(lbb_diag_value!= prev_lbb_diag_value)最終作為指示記錄的新列從一個值轉換到另一個值。

然后識別'onewire_cable'將是這樣的:

select * from (
...join...
) j where j.flip = 1 and j.lbb_diag_value = 'onewire_cable'

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM