簡體   English   中英

如何執行以下 SQL(或 PL/SQL)查詢

[英]How do I perform the following SQL (or PL/SQL) Query

如果面臨以下要求:用戶需要一個表,在該表中他可以看到員工 ID、員工姓名和員工不工作的天數。 原始數據存儲在下表中:

Employee: Emp_ID, Emp_Name

WorkDays: Emp_ID, Date

該過程是每當員工工作時,他的 ID 和當天的日期都會插入 WorkDays 表中。

現在我需要一個 SQL 或 PL/SQL 查詢,在其中我選擇一個日期范圍(fe 介於 2021 年 10 月 1 日和 2021 年 11 月 1 日之間)以及在此期間至少有 1 天沒有工作的每個員工(意味着有WorkDays 表中“缺少”特定 ID 和日期的一行),他將顯示在一行中,其中包含他沒有工作的日期。 日期都在一行的一列中,fe 用逗號分隔。

為了更好地理解,如果有兩名員工在那段時間沒有工作,那么決賽桌應該是這樣的:

Emp_ID | Emp_Name |             Hasn't Worked               |
1      | John     |      2021-10-01, 2021-10-03, 2021-10-06 |
3      | Mary     |      2021-10-02, 2021-10-03             |

我不希望我的代碼為我完成,而是在查詢表的問題上獲得幫助,在該表中我必須循環遍歷數據並在相應的行中顯示多個結果(日期)。

非常感謝您的幫助! 傑克

使用行生成器創建日歷,然后使用PARTITION OUTER JOIN並找到不匹配的行,然后聚合:

WITH calendar (day) AS (
  SELECT DATE '2021-10-01' FROM DUAL
UNION ALL
  SELECT day + 1 FROM calendar WHERE day < DATE '2021-11-01'
)
SELECT w.emp_id,
       MAX(emp_name) AS emp_name,
       LISTAGG(TO_CHAR(c.day, 'YYYY-MM-DD'), ', ') WITHIN GROUP (ORDER BY c.day)
         AS non_work_days
FROM   calendar c
       LEFT OUTER JOIN workdays w
       PARTITION BY (w.emp_id)
       ON (c.day = w."DATE")
       LEFT OUTER JOIN employee e
       ON (w.emp_id = e.emp_id)
WHERE  w."DATE" IS NULL
GROUP BY w.emp_id;

或者您可以使用CROSS JOIN

WITH calendar (day) AS (
  SELECT DATE '2021-10-01' FROM DUAL
UNION ALL
  SELECT day + 1 FROM calendar WHERE day < DATE '2021-11-01'
)
SELECT e.emp_id,
       MAX(e.emp_name) AS emp_name,
       LISTAGG(TO_CHAR(c.day, 'YYYY-MM-DD'), ', ') WITHIN GROUP (ORDER BY c.day)
         AS non_work_days
FROM   calendar c
       CROSS JOIN employee e
       LEFT OUTER JOIN workdays w
       ON (c.day = w."DATE" AND e.emp_id = w.emp_id)
WHERE  w."DATE" IS NULL
GROUP BY e.emp_id;

其中,對於樣本數據:

CREATE TABLE Employee (Emp_ID, Emp_Name) AS
SELECT 1, 'Alice' FROM DUAL UNION ALL
SELECT 2, 'Beryl' FROM DUAL;

CREATE TABLE WorkDays (Emp_ID, "DATE") AS
WITH calendar (dt) AS (
  SELECT DATE '2021-10-01' + LEVEL - 1 FROM DUAL CONNECT BY LEVEL <= 32
)
SELECT 1, dt FROM calendar WHERE dt NOT IN (DATE '2021-10-01', DATE '2021-10-03', DATE '2021-10-06')
UNION ALL
SELECT 2, dt FROM calendar WHERE dt NOT IN (DATE '2021-10-02', DATE '2021-10-03')

output:

EMP_ID EMP_NAME NON_WORK_DAYS
1 愛麗絲 2021-10-01, 2021-10-03, 2021-10-06
2 綠柱石 2021-10-02, 2021-10-03

db<> 在這里擺弄

暫無
暫無

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

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