簡體   English   中英

甲骨文:SQL; 當且僅當一列更改時選擇不同的記錄

[英]ORACLE: SQL; Select a distinct records if and only if one column changed

在此先感謝您的幫助。 當且僅當另一列更改時,我需要創建一個查詢來選擇不同的列。 但是,每條記錄都有一個 date_code,這使得每條記錄都是唯一的。 我想提取更改前的最后一條記錄以及更改后的最后一條記錄。

這是一個示例:帶有帳號、帶有日期代碼戳的公司名稱的客戶記錄。 我想在公司名稱更改之前獲得最后一條記錄。 即使客戶返回公司,特定公司的客戶的最后記錄也將是最后日期代碼。

表示例:表數據示例

預期結果:預期結果示例

您可以使用MATCH_RECOGNIZE

SELECT datecode,
       customer_account,
       company_name
FROM   table_name
MATCH_RECOGNIZE (
  PARTITION BY customer_account
  ORDER     BY datecode
  MEASURES
    LAST( datecode ) AS datecode,
    LAST( company_name ) AS company_name
  ONE ROW PER MATCH
  PATTERN ( company* same_company  )
  DEFINE
    company AS FIRST( company_name ) = NEXT( company_name )
)

其中,對於樣本數據:

CREATE TABLE table_name ( datecode, customer_account, company_name ) AS
SELECT DATE '2020-11-01', 10001000000004, 'Apple' FROM DUAL UNION ALL
SELECT DATE '2020-11-02', 10001000000004, 'Apple' FROM DUAL UNION ALL
SELECT DATE '2020-11-03', 10001000000004, 'Apple' FROM DUAL UNION ALL
SELECT DATE '2020-11-04', 10001000000004, 'Apple' FROM DUAL UNION ALL
SELECT DATE '2020-11-05', 10001000000004, 'Microsoft' FROM DUAL UNION ALL
SELECT DATE '2020-11-06', 10001000000004, 'Microsoft' FROM DUAL UNION ALL
SELECT DATE '2020-11-07', 10001000000004, 'Google' FROM DUAL UNION ALL
SELECT DATE '2020-11-08', 10001000000004, 'Google' FROM DUAL UNION ALL
SELECT DATE '2020-11-09', 10001000000004, 'Apple' FROM DUAL UNION ALL
SELECT DATE '2020-11-10', 10001000000004, 'Apple' FROM DUAL;

輸出:

\n日期代碼 |  CUSTOMER_ACCOUNT | 公司名\n :------------------ |  ---------------: |  :-----------\n 2020-11-04 00:00:00 |  10001000000004 | 蘋果       \n 2020-11-06 00:00:00 |  10001000000004 | 微軟   \n 2020-11-08 00:00:00 |  10001000000004 | 谷歌      \n 2020-11-10 00:00:00 |  10001000000004 | 蘋果       \n

db<> 在這里擺弄

您可以使用分析函數LAG/LEAD來計算下一行/上一行的值並將其與當前值進行比較。 這也適用於許多其他數據庫。

在這里擺弄

with q as (
  select a.*,
    lead(company_name, 1, '__')
      over(partition by customer_account order by datecode asc) as next_comp
  from cust_account a
)
select
  datecode,
  customer_account,
  company_name
from q
where company_name != next_comp
order by datecode asc

+---------+------------------+--------------+
|DATECODE | CUSTOMER_ACCOUNT | COMPANY_NAME |
+---------+------------------+--------------+
|20201104 | 10001000000004   | Apple        |
|20201106 | 10001000000004   | Microsoft    |
|20201108 | 10001000000004   | Google       |
|20201110 | 10001000000004   | Apple        |
+---------+------------------+--------------+

您可以使用簡單情況下的答案之一中提到的簡單lead功能case..when如下:

select * from
(select t.*,
       case
         when lead(company_name) over(partition by customer_account order by datecode) = company_name 
         then 0
         else 1
       end as result
  from cust_account t)
where result = 1

暫無
暫無

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

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