Office中国论坛/Access中国论坛
标题: [求助]请SQL高手相助:不用自定义函数,如何计算员工每月的请假天数(已解决) [打印本页]
作者: zyp 时间: 2005-11-2 18:12
标题: [求助]请SQL高手相助:不用自定义函数,如何计算员工每月的请假天数(已解决)
这个贴本来是发在ADP版块的,因去ADP版块的朋友较少,所以借这个人事旺盛的版块一用,请版主误删,谢谢!
[求助]不用自定义函数,如何计算员工每月的请假天数
在ADP中,有如下的资料表(员工请假记录):
Id
员工
起始日期
结束日期
1
张三
2005/10/1
2005/10/3
2
张三
2005/10/12
2005/10/12
3
张三
2005/10/24
2005/10/28
4
李四
2005/9/21
2005/10/15
5
李四
2005/10/25
2005/10/26
6
李四
2005/10/30
2005/11/15
7
王二
2005/9/15
2005/11/14
现在需计算员工在10月份的请假记录,应该为如下结果:<FONT face="Times New Roman">
<TABLE cellSpacing=0 cellPadding=0 border=1>
员工
请假天数
<TR>
张三
<TD vAlign=top width=96>
<FONT colo
作者: LucasLynn 时间: 2005-11-2 20:02
这个问题和昨天有人问我的一个生日查询的问题有些类似。因为我对ADP不熟悉,无法很快提供给你一个答案,在此提供一个思路:
你可以先对于本月内的跨月假期重新构建起始日期为均在当月内,然后对重新构建后的日期进行统计。
例如查询10月:
记录1:10.2-10.5
重新构建后为10.2-10.5
记录2:9.8-10.6
重新构建后为10.1-10.6
记录3:10.9-11.2
重新构建后为10.9-10.31
记录4:9.25-11.6
重新构建后为:10.1-10.31
[此贴子已经被作者于2005-11-2 12:05:06编辑过]
作者: secowu 时间: 2005-11-2 21:38
这种变通的想法真的很好,牧人,经常有特别有用的思路呵呵。。。。受益良多
作者: zyp 时间: 2005-11-3 06:31
LucasLynn版主果然不同凡响,谢谢!我只考虑该用什么的SQL内建函数和方法,而没有考虑到版主的方法我先测试一下是否可以实现。
作者: eyewitnes 时间: 2005-11-3 23:34
以下是引用zyp在2005-11-2 22:31:00的发言:
LucasLynn版主果然不同凡响,谢谢!
我只考虑该用什么的SQL内建函数和方法,而没有考虑到版主的方法
我先测试一下是否可以实现。
测试后能否分享一下?我琢磨了半天都没办法通过视图实现,以下是我目前能想到,而且在SQL2000中通过了的:
SELECT 姓名, 起始日期, 结束日期
FROM dbo.请假明细表
WHERE (MONTH(GETDATE()) BETWEEN MONTH(起始日期) AND MONTH(结束日期))
作者: zyp 时间: 2005-11-4 00:54
好的,因临时有点任务,可能会推迟几天才会有结果eyewitnes 的方法尚不能实现的我目的。谢谢!
作者: 海狸先生 时间: 2005-11-4 04:18
SELECT 员工, sum(IIf(结束日期>#10/31/2005#,#10/31/2005#,结束日期)-IIf(起始日期<#10/1/2005#,#10/1/2005#,起始日期)+1)
FROM Sheet1
GROUP BY 员工;
作者: 海狸先生 时间: 2005-11-4 04:20
我搞不懂 1)起始日和终止日均为当月的:请假天数 = 终止日 - 起始日 + 1 :如 10月1日到10月5日
(2)起始日为当月之前,终止日为当月:请假天数 = 终止日 - 当月1号 (或day(终止日)) : 如9月1日到10月5日两个 10月1日到10月5日都没上班,为什么一个 算 5天 ,一个却只算4天 ?
作者: zyp 时间: 2005-11-4 21:52
以下是引用海狸先生在2005-11-3 20:20:00的发言:
我搞不懂
1)起始日和终止日均为当月的:请假天数 = 终止日 - 起始日 + 1 :如 10月1日到10月5日
(2)起始日为当月之前,终止日为当月:请假天数 = 终止日 - 当月1号 (或day(终止日)) : 如9月1日到10月5日
两个 10月1日到10月5日都没上班,为什么一个 算 5天 ,一个却只算4天 ?
谢谢海狸版主
对不起,我是不小心打漏了,应该是两个都是5天:
1)起始日和终止日均为当月的:请假天数 = 终止日 - 起始日 + 1 :如 10月1日到10月5日
(2)起始日为当月之前,终止日为当月:请假天数 = 终止日 - 当月1号 + 1 (或day(终止日)) : 如9月1日到10月5日
[此贴子已经被作者于2005-11-4 13:53:55编辑过]
作者: zyp 时间: 2005-11-4 21:59
以下是引用海狸先生在2005-11-3 20:18:00的发言:
SELECT 员工, sum(IIf(结束日期>#10/31/2005#,#10/31/2005#,结束日期)-IIf(起始日期<#10/1/2005#,#10/1/2005#,起始日期)+1)
FROM Sheet1
GROUP BY 员工;
版主的方法在MDB中绝对没问题,但我是用在ADP中的,没用iif函数
作者: 海狸先生 时间: 2005-11-4 22:20
在ADP中 true 还是等于-1的吗?如果是,那么SELECT 员工, sum((起始日期<#10/1/2005#)*#10/1/2005#+(起始日期>=#10/1/2005#)*起始日期-(结束日期>#10/31/2005#)*#10/31/2005#-(结束日期<=#10/31/2005#)*结束日期+1)
FROM Sheet1
GROUP BY 员工;
作者: 海狸先生 时间: 2005-11-4 22:23
再加一个 where 结束日期>=#2005-10-1# 更保险
作者: eyewitnes 时间: 2005-11-5 02:41
SUM
返回表达式中所有值的和,或只返回 DISTINCT 值。SUM 只能用于数字列。空值将被忽略
日期型的。。。估计不行,最令我不解的是SQL2000提示“<”附近有错误。。。按说SQL2000不可能不支持比较运算吧?
作者: 海狸先生 时间: 2005-11-5 04:52
呵呵,在MDB中是可以的
作者: eyewitnes 时间: 2005-11-5 17:01
这个难在怎样将跨月的日期转变成本月的第一日或者最后一日,,想不出来哇
作者: zyp 时间: 2005-11-6 01:25
多谢LucasLynn 版主的指点,问题已解决
下面是在ADP中写的存储过程,其中@firstDay为要查询月的第一天,@LastDay为要查询的最后一天
Alter Procedure "JiaTsM"
(@FirstDay datetime,@LastDay DateTime)
As
declare @Y int,@M int
set @Y=year(@FirstDay)
set @M=month(@FirstDay)
SELECT 员工,
Convert(int,Case When 终止日期>@LastDay Then @LastDay Else 终止日期
End-Case When 起始日期<@FirstDay Then @FirstDay Else 起始日期 End)
As 天数
From 请假表
WHERE
((year(起始日期)=@Y and month(起始日期)=@M) or
(year(终止日期)=@Y and month(终止日期)=@M) or
(起始日期<@FirstDay and 终止日期>@LastDay))
return
[此贴子已经被作者于2005-11-5 17:26:58编辑过]
作者: zyp 时间: 2005-11-6 01:30
以下是引用海狸先生在2005-11-4 14:20:00的发言:
在ADP中 true 还是等于-1的吗?如果是,那么
SELECT 员工, sum((起始日期<#10/1/2005#)*#10/1/2005#+(起始日期>=#10/1/2005#)*起始日期-(结束日期>#10/31/2005#)*#10/31/2005#-(结束日期<=#10/31/2005#)*结束日期+1)
FROM Sheet1
GROUP BY 员工;
谢谢海狸版主,在ADP中True为1,False为0
再次谢谢两位版主的提点,及各位网友的热情帮助[em24][em24][em24][em24][em25][em25][em25][em25][em26][em26][em26][em26][em27][em27][em27][em27]
[此贴子已经被作者于2005-11-5 17:31:53编辑过]
作者: 海狸先生 时间: 2005-11-8 15:35
那这样应该可以吧SELECT 员工, sum((结束日期>#10/31/2005#)*#10/31/2005#+(结束日期<=#10/31/2005#)*结束日期-(起始日期<#10/1/2005#)*#10/1/2005#-(起始日期>=#10/1/2005#)*起始日期+1)
FROM Sheet1
GROUP BY 员工;
作者: eyewitnes 时间: 2005-11-8 18:17
以下是引用海狸先生在2005-11-8 7:35:00的发言:
那这样应该可以吧
SELECT 员工, sum((结束日期>#10/31/2005#)*#10/31/2005#+(结束日期<=#10/31/2005#)*结束日期-(起始日期<#10/1/2005#)*#10/1/2005#-(起始日期>=#10/1/2005#)*起始日期+1)
FROM Sheet1
GROUP BY 员工;
SELECT 子句错误:'>' 附近的表达式。
SELECT 子句错误:'FROM' 附近的表达式。
丢失 FROM 子句。
无法对查询文本做语法分析。
不行呢SQL2000中通不过
作者: 海狸先生 时间: 2005-11-8 19:19
啊。sql2000不支持比较?
作者: zyp 时间: 2005-11-8 22:38
以下是引用eyewitnes在2005-11-8 10:17:00的发言:
SELECT 子句错误:'>' 附近的表达式。
SELECT 子句错误:'FROM' 附近的表达式。
丢失 FROM 子句。
无法对查询文本做语法分析。
不行呢SQL2000中通不过
海狸版主的代碼我在SQL 7.0中也沒通過,提示與你的差不多.
謝謝海狸版主,你所寫的表達式太高深了,我看不太明白(如整數*日期是什麼),能不能注解一下,或許順著你的思路,在adp中變通一下,就能實現目的了.
謝謝!
[此贴子已经被作者于2005-11-8 16:40:07编辑过]
作者: zyp 时间: 2005-11-9 05:38
在SQL中,不支持用日期*数字,报告数据类型不同不可以进行这样的操作
作者: 海狸先生 时间: 2005-11-9 06:05
'日期其实就是 数字 如 2005-10-1就是38636SELECT 员工, sum(
(结束日期>#10/31/2005#) '大于则为1,否则为0
*#10/31/2005#
+
(结束日期<=#10/31/2005#) '大于则为0,否则为1 ,结合一下,可以推出结果
*结束日期
-
(起始日期<#10/1/2005#)
*#10/1/2005#
-
(起始日期>=#10/1/2005#)
*起始日期
+1)
FROM Sheet1 GROUP BY 员工;
作者: eyewitnes 时间: 2005-11-9 18:44
现在看来,好像是只能在触发器或者存储过程才支持比较运算。。视图中不支持?应该不可能吖。。是不是我们的语法搞错了??
作者: eyewitnes 时间: 2005-11-9 18:50
存储过程是通过了,不过如果用存储过程的话,我想在表里边增加一个字段记录实际请假天数,用触发器来刷新可能会更好
作者: zyp 时间: 2005-11-10 07:23
以下是引用海狸先生在2005-11-8 22:05:00的发言:
'日期其实就是 数字 如 2005-10-1就是38636
谢谢海狸版主,在ADP中好像不支持这个算法。
作者: zyp 时间: 2005-11-10 07:25
以下是引用eyewitnes在2005-11-9 10:50:00的发言:
存储过程是通过了,不过如果用存储过程的话,我想在表里边增加一个字段记录实际请假天数,用触发器来刷新可能会更好
直接用计算字段不行吗?
作者: eyewitnes 时间: 2005-11-12 18:24
计算字段?
作者: eyewitnes 时间: 2005-11-12 18:31
CREATE PROCEDURE dbo.ABC
@Month as int
AS
BEGIN
Declare @Start as smalldatetime -- '10/01/2005'
Declare @End as smalldatetime -- '11/01/2005'
SET @Start = Cast((cast(@Month as char(2)) + '/01/' + year(getdate())) as smalldatetime)
SET @Start = Cast((cast((@Month+1) as char(2)) + '/01/' + year(getdate())) as smalldatetime)
SELECT 姓名 ,
DATEDIFF(day,
CASE 起始日期
when 起始日期>=@End then @End
when 起始日期<@Start then @Start
Else 起始日期
END
,
CASE 结束日期
when 结束日期>=@End then @End
when 结束日期<@Start then @Start
Else 结束日期
END
)
AS 请假日期
FROM 表名
END
-- 如果是五天工作制,还要考虑消除周末
原帖来自于网易社区:http://p5.club.163.com/viewArticleByWWW.m?boardId=database&articleId=database_1075e61c
抄回来得7444390 以上均为抄袭,呵呵
[此贴子已经被作者于2005-11-12 11:03:35编辑过]
作者: fuyvn 时间: 2005-11-12 20:01
好象忘了一件小事. 那就是 ACCESS中 日期是 # 开头 和 结尾. SQL中 是以 ' 开头结尾.
欢迎光临 Office中国论坛/Access中国论坛 (http://www.office-cn.net/) |
Powered by Discuz! X3.3 |