我需要计算每周工作的人数。
这是我的人员表(日期是美国格式):
name | surname| date_of_entry | date_of_exit
-----|--------|---------------|-------------
foo | bar | 1/1/2006 | 1/8/2006
foo1 | bar1 | 1/5/2010 |
foo2 | bar2 | 2/3/2015 | 3/4/2015
而且我希望某一年能够在这段时间内拥有适当人数的所有周数。
我希望你理解我,因为英语不是我的母语抱歉。
我做了一些研究,根据我的理解,我需要创建一个表格,从2006年1月1日开始到结束时间#34;现在" (因为没有退出日期的人仍然在工作)根据上面的例子,如果他在这个星期工作的话,能够测试每个人,所以我可以在我的查询中计算他。
我还是学生程序员,但对我来说这似乎是一个非常复杂的SQL查询。
2006年查询的预期输出(新年从星期一开始):
week_number | count
------------|------
1 | 1
2 | 1
3 | 0
etc.. | 0
直到2010年5月1日,所有周都在场上有1个"计数" 然后查询2015年:
week_number | count
------------|------
1 | 1
2 | 1
... | 1
9 | 2
... | 2
14 | 1
... | 1
如果有人可以帮我解决这个问题,那就太棒了,谢谢!
答案 0 :(得分:0)
您可以创建查询以查找工作周数:
Select
[name],
surname,
year,
week
From
PeopleTable,
WeekTable
Where
(date_of_entry <= week_start And DateDiff("d", week_start, date_of_exit) >= 3)
Or
(date_of_entry >= week_start And date_of_exit <= week_end
And
DateDiff("d", date_of_entry, date_of_exit >= 3)
Or
(DateDiff("d", date_of_entry, week_end) >= 3 And date_of_exit >= week_end)
Group By
[name],
surname,
year,
week
现在,保存并创建一个新查询,其中使用WeekTable作为源(列出所有周),并使用外部联接到上面的查询(列出工作周)。在此,分组按年和周,并添加计数以获得每周工作员工的数量。
答案 1 :(得分:0)
你很幸运我必须改变主意15分钟。
创建一个名为fill_parent
的新表,其中包含以下字段
fill_parent
:autonumber Calendar
:号码id
:号码在模块中,添加以下代码并执行它(F5):
Cal_Year
Cal_Week
表现在可以使用了:
Private Sub Create_Calendar_table()
Dim Y As Integer
Dim W As Integer
For Y = 2006 To 2016
For W = 1 To 52
DoCmd.RunSQL "INSERT INTO Calendar (cal_year, cal_week) VALUES (" & Y & "," & W & ")"
Next W
Next Y
End Sub
请注意,我在欧洲所以我的日期是DD / MM。这不会影响您的结果。
我分解,所以你理解这个过程。
首先我们需要在日历表中创建年/周的日期,这可以像这样实现
Calendar
接下来,由于我们将处理日期范围,因此当人们的exit_date为ID Cal_year Cal_week
1 2006 1
2 2006 2
3 2006 3
4 2006 4
5 2006 5
and so on...
时,将当前日期归因于此是非常重要的,如下所示:
SELECT Cal_year, Cal_week, DateAdd("ww",Cal_week,DateSerial(Cal_year,1,1)) AS thedate
FROM Calendar
Cal_year Cal_week thedate
2006 1 8/01/2006
2006 2 15/01/2006
2006 3 22/01/2006
2006 4 29/01/2006
2006 5 5/02/2006
and so on...
准备好了这个领域。
然后,诀窍。
我们需要NULL
我们的日历表与人员表一起返回一个人在场的每周的记录。
实现这一目标的关键是nz(date_of_exit, Now)
JOIN
请注意,如果您需要自2006年以来的所有周,即使是那些没有人在场的人,也只需使用ON...BETWEEN...AND
更改SELECT C.Cal_year, C.Cal_Week, P.pname, P.psurname, P.date_of_entry, nz(P.date_of_exit, Now) AS exit_date
FROM [Calendar] C
INNER JOIN ( SELECT [Name] AS pname, [surname] as psurname, date_of_entry, date_of_exit
FROM people
) P
ON (DateAdd("ww",C.Cal_week,DateSerial(C.Cal_year,1,1)) BETWEEN P.date_of_entry AND nz(P.date_of_exit, Now))
ORDER BY C.Cal_year, C.Cal_Week
Cal_year Cal_Week pname psurname date_of_entry exit_date
2006 1 foo bar 1/01/2006 8/01/2006
2010 1 foo1 bar1 5/01/2010 22/04/2016 13:04:39
2010 2 foo1 bar1 5/01/2010 22/04/2016 13:04:39
2010 3 foo1 bar1 5/01/2010 22/04/2016 13:04:39
2010 4 foo1 bar1 5/01/2010 22/04/2016 13:04:39
最后,我们利用之前的查询通过在日历表的年份和周上执行INNER JOIN
来计算在线状态,并在LEFT JOIN
子句中指定2015年,否则它将计算在内自2006年以来的一切。这意味着很容易计算任何一年的存在。
GROUP BY
好吧,我最后花了40分钟......