簡體   English   中英

查詢以獲取給定日期/期間的員工數據

[英]Query to get employees data in a given date/period

我需要幫助才能從一個復雜的數據庫中獲取員工工作數據。

我將嘗試恢復數據庫組織:

  1. 員工表,至少如下
id    | name
16063 | Jane
17594 | Joe
  1. 帶有開始/結束工作期間日期的歷史表:
id   | id_employee | start    | end
1518 | 16063       | 20110701 | 20991231
1576 | 17594       | 20201123 | 20210715
1577 | 17594       | 20210716 | 20991231
  1. 雇佣類型
id | description
3  | permanent
4  | fixed-term
  1. 就業狀況
id   | id_employee | start    | id_employment
1518 | 16063       | 20210901 | 3
1575 | 17594       | 20201123 | 4
1576 | 17594       | 20210716 | 3
  1. 職位
id | description
5  | Assistant
26 | Collaborator
56 | Manager
  1. 位置狀態
id   | id_employee | start    | id_position
1545 | 16063       | 20190101 | 5
1546 | 16063       | 20210901 | 26
1603 | 17594       | 20201123 | 56
  1. 水平
id | description
7  | C
9  | D
20 | ME1B
  1. level_status
id   | id_employee | start    | id_level
1525 | 16063       | 20190101 | 7
1526 | 16063       | 20210901 | 9
1583 | 17594       | 20201123 | 20

我需要一個查詢的幫助,fi 在 2021 年 1 月 1 日和 12 月 31 日期間返回:

id    | name | employment | position     | level | start      | end
16063 | Jane | permanent  | assistant    | C     | 20110701   | 20991231
16063 | Jane | permanent  | collaborator | D     | 20110701   | 20991231
17594 | Joe  | fixed-term | manager      | ME1B  | 20201123   | 20210715
17594 | Joe  | permanent  | manager      | ME1B  | 20210716   | 20991231

雖然僅在 2021 年 1 月 1 日進行測試,但它應該返回:

id    | name | employment | position     | level | start    | end
16063 | Jane | permanent  | assistant    | C     | 20110701 | 20991231
17594 | Joe  | fixed-term | manager      | ME1B  | 20201123 | 20210715

我正在使用以下查詢:

SELECT employees.id,employees.name,employment_type.description,positions.description,levels.description,history.start,history.end
FROM history 
LEFT JOIN employees ON employees.id=history.id_employee 
LEFT JOIN employment_status ON employees.id=employment_status.id_employee 
LEFT JOIN employment_type ON employment_status.id_employment=employment_type.id 
LEFT JOIN position_status ON employees.id=position_status.id_employee 
LEFT JOIN positions ON position_status.id_position=positions.id 
LEFT JOIN level_status ON employees.id=level_status.id_employee 
LEFT JOIN levels ON level_status.id_level=levels.id 
WHERE (history.start <= '20210101' OR history.end <= '20211231');

這給了我一個不正確的 output:

16063 | Jane | permanent  | assistant    | C    | 20110701 | 20991231
16063 | Jane | permanent  | assistant    | D    | 20110701 | 20991231
16063 | Jane | permanent  | collaborator | C    | 20110701 | 20991231
16063 | Jane | permanent  | collaborator | D    | 20110701 | 20991231
17594 | Joe  | permanent  | manager      | ME1B | 20201123 | 20210715
17594 | Joe  | fixed-term | manager      | ME1B | 20201123 | 20210715

正如您所看到的,對於 Jane,它創建了所有頭寸和級別組合,而對於 Joe,它為“永久”報告了相同的定期日期組合。

這是示例數據庫的 sql(如果有幫助)提前致謝

BEGIN TRANSACTION;
CREATE TABLE IF NOT EXISTS "employees" (
    "id"    INTEGER NOT NULL,
    "name"  TEXT NOT NULL,
    PRIMARY KEY("id" AUTOINCREMENT)
);
CREATE TABLE IF NOT EXISTS "employment_type" (
    "id"    INTEGER NOT NULL,
    "description"   TEXT NOT NULL,
    PRIMARY KEY("id" AUTOINCREMENT)
);
CREATE TABLE IF NOT EXISTS "positions" (
    "id"    INTEGER NOT NULL,
    "description"   TEXT NOT NULL,
    PRIMARY KEY("id" AUTOINCREMENT)
);
CREATE TABLE IF NOT EXISTS "levels" (
    "id"    INTEGER NOT NULL,
    "description"   TEXT NOT NULL,
    PRIMARY KEY("id" AUTOINCREMENT)
);
CREATE TABLE IF NOT EXISTS "employment_status" (
    "id"    INTEGER NOT NULL,
    "id_employee"   INTEGER NOT NULL,
    "start" INTEGER NOT NULL,
    "id_employment" INTEGER NOT NULL,
    PRIMARY KEY("id" AUTOINCREMENT)
);
CREATE TABLE IF NOT EXISTS "history" (
    "id"    INTEGER NOT NULL,
    "id_employee"   INTEGER NOT NULL,
    "start" INTEGER NOT NULL,
    "end"   INTEGER NOT NULL,
    PRIMARY KEY("id" AUTOINCREMENT)
);
CREATE TABLE IF NOT EXISTS "level_status" (
    "id"    INTEGER NOT NULL,
    "id_employee"   INTEGER NOT NULL,
    "start" INTEGER NOT NULL,
    "id_level"  INTEGER NOT NULL,
    PRIMARY KEY("id" AUTOINCREMENT)
);
CREATE TABLE IF NOT EXISTS "position_status" (
    "id"    INTEGER NOT NULL,
    "id_employee"   INTEGER NOT NULL,
    "start" INTEGER NOT NULL,
    "id_position"   INTEGER NOT NULL,
    PRIMARY KEY("id" AUTOINCREMENT)
);
INSERT INTO "employees" VALUES (16063,'Jane');
INSERT INTO "employees" VALUES (17594,'Joe');
INSERT INTO "employment_type" VALUES (3,'permanent');
INSERT INTO "employment_type" VALUES (4,'fixed-term');
INSERT INTO "positions" VALUES (5,'Assistant');
INSERT INTO "positions" VALUES (26,'Collaborator');
INSERT INTO "positions" VALUES (56,'Manager');
INSERT INTO "levels" VALUES (7,'C');
INSERT INTO "levels" VALUES (9,'D');
INSERT INTO "levels" VALUES (20,'ME1B');
INSERT INTO "employment_status" VALUES (1,16063,20210901,3);
INSERT INTO "employment_status" VALUES (2,17594,20201123,4);
INSERT INTO "employment_status" VALUES (3,17594,20210716,3);
INSERT INTO "history" VALUES (1,16063,20110701,20991231);
INSERT INTO "history" VALUES (2,17594,20201123,20210715);
INSERT INTO "history" VALUES (3,17594,20210716,20991231);
INSERT INTO "level_status" VALUES (1,16063,20190101,7);
INSERT INTO "level_status" VALUES (2,16063,20210901,9);
INSERT INTO "level_status" VALUES (3,17594,20201123,20);
INSERT INTO "position_status" VALUES (1,16063,20190101,5);
INSERT INTO "position_status" VALUES (2,16063,20210901,26);
INSERT INTO "position_status" VALUES (3,17594,20201123,56);
COMMIT;

不確定這是否是最有效的方法。

但是有了足夠的 row_numbers,你就可以擺脫重復。

另請注意,無論歷史記錄如何,這都會從employee_type、position 和級別返回最新的。
因為只有歷史才有日期的標准。

 SELECT emp.id as emp_id, emp.name as emp_name, emptype.description as type_desc, pos.description as pos_desc, lvl.description as lvl_desc, hist.start as hist_start, hist.end as hist_end FROM employees AS emp INNER JOIN ( select id_employee, h.start, h.end, row_number() over (partition by id_employee order by start desc) as rn from history h where (h.start <= '20210101' OR h.end <= '20211231') ) AS hist ON hist.id_employee = emp.id AND hist.rn = 1 LEFT JOIN ( select id_employee, id_employment, row_number() over (partition by id_employee order by start desc) as rn from employment_status ) AS empstat ON empstat.id_employee = emp.id AND empstat.rn = 1 LEFT JOIN employment_type AS emptype ON emptype.id = empstat.id_employment LEFT JOIN ( select id_employee, id_position, row_number() over (partition by id_employee order by start desc) as rn from position_status ) AS posstat ON posstat.id_employee = emp.id AND posstat.rn = 1 LEFT JOIN positions AS pos ON pos.id = posstat.id_position LEFT JOIN ( select id_employee, id_level, row_number() over (partition by id_employee order by start desc) as rn from level_status ) AS lvlstat ON lvlstat.id_employee = emp.id AND lvlstat.rn = 1 LEFT JOIN levels AS lvl ON lvl.id = lvlstat.id_level;
emp_id emp_name type_desc pos_desc lvl_desc hist_start hist_end
16063 永恆的 合作者 D 20110701 20991231
17594 永恆的 經理 ME1B 20201123 20210715

關於db<>fiddle 的演示在這里

暫無
暫無

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

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