获取每月出现一次以上的ID

时间:2019-01-25 13:44:15

标签: postgresql

我需要创建一个查询,当[对于一个employee_id在同一个月中有多个project_id时,请选择“ employee_id,project_id,start_date和end_date。” 我的想法是,我不知道如何查看一个employee_id在同一个月中是否有多个project_id。我知道一种方法是在'2010-01-01'和'2010-02-01'之间使用,但这不是正确的方法,因为我不知道大约在哪个日期开始,所以需要动态的。 enter image description here

Employee_id Project_id  Project_ Employee_id    Start_date  End_date    occupied    status  Role_id key

"47"    "96"    "1440"  "2019-04-07"    "2019-04-30"    100 "ON_PROJECT"    "3" "NO"
"47"    "96"    "1441"  "2019-04-05"    "2019-04-20"    100 "ON_PROJECT"    "250"   "NO"
"47"    "131"   "1442"  "2019-04-07"    "2019-04-15"    100 "ON_PROJECT"    "3" "NO"

当Start_date End_date在同一月份时,例如对于相同的Employee_id和Project_id,而Start_date,End_date在同一月份,则需要这些。 我需要结果像这个例子一样
前 (47,96,1440,'2019-04-07','2019-04-30'),(47,96,1441,'2019-04-06','2019-04-20'),仅用于一个月,我知道有很多行 那也许是相同的结果,但是我只需要工作一个,就不会在同一个月中有超过2个Employee_id和Project_id。

1 个答案:

答案 0 :(得分:2)

demo:db<>fiddle

(不是为了进行更多测试,我将1439 end_date行更改为几个月后,将project_id更改为132,并在最后一行添加了{{ 1}},不应该显示)

employee_id = 48
  1. SELECT employee_id, project_id, MIN(start_date), MAX(end_date) FROM emp, generate_series(date_trunc('month', start_date), date_trunc('month', end_date) , interval '1 month') gs GROUP BY employee_id, project_id HAVING COUNT(gs) >= 2 采用每月的第一天。这是一种归一化,因为我只对几个月感兴趣,而不对实际日子感兴趣。
  2. date_trunc为项目条目存在的每个月生成行。 (请参阅项目generate_series,该项目在4月至6月的三个月内出现。)这种扩展允许按项目/员工分组并计算不同的月份
  3. 132GROUPemployee_id组并计算它们出现的月份。
  4. 一个月以上的组将通过project_ids子句进行过滤。


对要求进行一些更改后:

使用window function COUNT可以对特定组的行进行计数,而无需进行汇总。因此,HAVING将组的计数添加为新列,然后可以对其进行过滤。

demo:db<>fiddle

如果COUNT(*) OVER()start_date在同一月份:

end_date

否则,您将不得不扩展项目出现的所有月份(如上所述):

SELECT 
    employee_id,
    project_id,
    start_date,
    end_date
FROM (
    SELECT
        *,
        COUNT(*) OVER (PARTITION BY employee_id, project_id, date_trunc('month', start_date))
    FROM
       emp_same
) s
WHERE count >= 2