我正在嘗試從員工串列中獲取作業編號。如果他們多年來沒有移動部門,那么這應該被視為一份作業。一旦他們搬到一個新部門,那應該被視為一份新作業。我面臨的問題是他們是否搬回一個部門,我的要求也應該被視為一份新作業。所以一個流程會像:
- 銷售 -> 作業 1
- IT -> 作業 2
- 銷售 -> 作業 3
- 市場營銷 -> 作業 4。
我在下面做了一個超級簡化的查詢來演示我想要實作的目標:
SELECT RANK() OVER(ORDER BY last_year_in_role) JOB_NO, name, Role
FROM
(
SELECT MAX(years_at_company) last_year_in_role, Name, Role
FROM (
SELECT 'Bob' name, 1 years_at_company, 'Sales' role FROM DUAL
UNION
SELECT 'Bob', 2, 'Sales' FROM DUAL
UNION
SELECT 'Bob', 3, 'Sales' FROM DUAL
UNION
SELECT 'Bob', 4, 'IT' FROM DUAL
UNION
SELECT 'Bob', 5, 'Sales' FROM DUAL
UNION
SELECT 'Bob', 6, 'Marketing' FROM DUAL
)
GROUP BY Name, Role
)
;
這會產生以下結果:

這是錯誤的,因為它一直將 SALES 的時間組合在一起,即使資料中斷。我覺得這個問題可以通過 WINDOW 函式以某種方式在 ROLE 上進行磁區來解決,但我沒有成功。
uj5u.com熱心網友回復:
由于這是一個間隙和島嶼問題,其中“海灘”被定義為部門變更。您可以使用LAG()分析功能檢測它們。例如,您可以執行以下操作:
with data as (
SELECT 'Bob' name, 1 years_at_company, 'Sales' role FROM DUAL
UNION
SELECT 'Bob', 2, 'Sales' FROM DUAL
UNION
SELECT 'Bob', 3, 'Sales' FROM DUAL
UNION
SELECT 'Bob', 4, 'IT' FROM DUAL
UNION
SELECT 'Bob', 5, 'Sales' FROM DUAL
UNION
SELECT 'Bob', 6, 'Marketing' FROM DUAL
)
select *
from (
select d.*,
case when role = lag(role) over(partition by name order by years_at_company)
then 0 else 1 end as beach
from data d
) x
order by name, years_at_company
結果:
NAME YEARS_AT_COMPANY ROLE BEACH
----- ----------------- ---------- -----
Bob 1 Sales 1
Bob 2 Sales 0
Bob 3 Sales 0
Bob 4 IT 1
Bob 5 Sales 1
Bob 6 Marketing 1
請參閱db<>fiddle 上的運行示例。
上面的查詢預處理資料以生成beach列。有了它,您可以清楚地區分哪些行實際代表新作業,哪些不代表。
您可以繼續處理資料以根據需要對其進行聚合或過濾,但這應該會為您提供所需的所有資訊。
uj5u.com熱心網友回復:
在 12.1 及更高版本中,最佳(最簡單、最高效和最優雅)的解決方案使用以下match_recognize子句:
select name, job_no, role
from (
SELECT 'Bob' name, 1 years_at_company, 'Sales' role
FROM DUAL UNION ALL
SELECT 'Bob', 2, 'Sales' FROM DUAL UNION ALL
SELECT 'Bob', 3, 'Sales' FROM DUAL UNION ALL
SELECT 'Bob', 4, 'IT' FROM DUAL UNION ALL
SELECT 'Bob', 5, 'Sales' FROM DUAL UNION ALL
SELECT 'Bob', 6, 'Marketing' FROM DUAL
)
match_recognize(
partition by name
order by years_at_company
measures match_number() as job_no, a.role as role
pattern (a b*)
define b as role = a.role
);
NAME JOB_NO ROLE
---- ------ ---------
Bob 1 Sales
Bob 2 IT
Bob 3 Sales
Bob 4 Marketing
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/357307.html
上一篇:如何修復這個MYSQL//Phpmyadmin錯誤?[復制]
下一篇:排除具有重復列值的行的運行總和
