最近公司需要人力资源部需要写一张报表,计算人员距离退休的天数和日期,现附上自己写是sql脚本(仅供参考),如下:
select a.pk_psndoc,--员工信息主键
a.code psndoc_code,--人员编码
a.name psndoc_name,--人员姓名
c.pk_psnjob,--工作信息主键
c.clerkcode,--员工号
a.birthdate,--出生日期
a.age,--年龄
case when a.sex = 1 then '男' when a.sex = 2 then '女' end sex,--性别
c.pk_org,--组织主键
d.code org_code,--组织编码
d.name org_name,--组织名称
e.pk_dept,--部门主键
e.code dept_code,--部门编码
e.name dept_name,--部门名称
f.pk_psncl,--人员类型主键
f.name psncl_name,--人员类型
h.pk_job,--职务主键
h.jobname,--职务
g.pk_post,--岗位主键
g.postname,--岗位
case when c.poststat = 'Y' then '是' else '否' end poststat,--是否在岗
b.joinsysdate,--进入集团时间
b.corpworkage,--集团工龄
b.begindate,--进入日期
b.orgglbdef3,--参加工作日期
b.orgglbdef7,--工龄
b.orgglbdef1,--进入报社时间
b.orgglbdef2,--报社社龄
case
when a.sex = 1 then datediff(dd, GETDATE(), dateadd(yy, 60, a.birthdate))
when a.sex = 2 then datediff(dd, GETDATE(), dateadd(yy, 55, a.birthdate)) end retire_days,--离退休天数
convert(char(10), dateadd(dd, case
when a.sex = 1 then datediff(dd, GETDATE(), dateadd(yy, 60, a.birthdate))
when a.sex = 2 then datediff(dd, GETDATE(), dateadd(yy, 55, a.birthdate)) end,
getdate()), 126) retiredate--离退休日期
from bd_psndoc a
inner join hi_psnorg b on a.pk_psndoc = b.pk_psndoc
inner join hi_psnjob c on b.pk_psnorg = c.pk_psnorg
inner join org_orgs d on c.pk_org = d.pk_org
inner join org_dept e on c.pk_dept = e.pk_dept
inner join bd_psncl f on c.pk_psncl = f.pk_psncl
inner join om_job h on c.pk_job = h.pk_job
inner join om_post g on c.pk_post = g.pk_post
where b.lastflag = 'Y'
and b.indocflag = 'Y'
and b.endflag = 'N'
and b.psntype = 0
and c.ismainjob = 'Y'
and c.lastflag = 'Y'
and c.endflag = 'N'
在NC65 【HR分析报表】-【分析模型-集团】节点下的sql如下:
select a.pk_psndoc,--员工信息主键
a.code psndoc_code,--人员编码
a.name psndoc_name,--人员姓名
c.pk_psnjob,--工作信息主键
c.clerkcode,--员工号
a.birthdate,--出生日期
a.age,--年龄
case when a.sex = 1 then '男' when a.sex = 2 then '女' end sex,--性别
c.pk_org,--组织主键
d.code org_code,--组织编码
d.name org_name,--组织名称
e.pk_dept,--部门主键
e.code dept_code,--部门编码
e.name dept_name,--部门名称
f.pk_psncl,--人员类型主键
f.name psncl_name,--人员类型
h.pk_job,--职务主键
h.jobname,--职务
g.pk_post,--岗位主键
g.postname,--岗位
case when c.poststat = 'Y' then '是' else '否' end poststat,--是否在岗
b.joinsysdate,--进入集团时间
b.corpworkage,--集团工龄
b.begindate,--进入日期
b.orgglbdef3,--参加工作日期
b.orgglbdef7,--工龄
b.orgglbdef1,--进入报社时间
b.orgglbdef2,--报社社龄
a.pk_group,--集团主键
case
when a.sex = 1 then datediff('dd', GETDATE(), dateadd('yy', 60, a.birthdate))
when a.sex = 2 then datediff('dd', GETDATE(), dateadd('yy', 55, a.birthdate)) end retire_days,--离退休天数
convert(char(10), dateadd('dd', case
when a.sex = 1 then datediff('dd', GETDATE(), dateadd('yy', 60, a.birthdate))
when a.sex = 2 then datediff('dd', GETDATE(), dateadd('yy', 55, a.birthdate)) end,
getdate()), 126) retiredate--离退休日期
from bd_psndoc a
inner join hi_psnorg b on a.pk_psndoc = b.pk_psndoc
inner join hi_psnjob c on b.pk_psnorg = c.pk_psnorg
inner join org_orgs d on c.pk_org = d.pk_org
inner join org_dept e on c.pk_dept = e.pk_dept
inner join bd_psncl f on c.pk_psncl = f.pk_psncl
inner join om_job h on c.pk_job = h.pk_job
inner join om_post g on c.pk_post = g.pk_post
where b.lastflag = 'Y'
and b.indocflag = 'Y'
and b.endflag = 'N'
and b.psntype = 0
and c.ismainjob = 'Y'
and c.lastflag = 'Y'
and c.endflag = 'N'
and a.pk_psndoc in (parameter('psndoc'))
and c.pk_org in (parameter('org'))
and e.pk_dept in (parameter('dept'))
and f.pk_psncl in (parameter('psncl'))
and g.pk_post in (parameter('post'))
and h.pk_job in (parameter('job'))
and a.sex=parameter('sex')
and c.pk_org in (select s.pk_org from sm_user u inner join sm_user_role ur on u.cuserid=ur.cuserid
inner join sm_subject_org s on s.subjectid=ur.pk_role where u.cuserid=macro('LoginUser'))
我设置了查询参数,所以sql中使用了parameter()函数,在NC的语义模型中,datediff(),datediff()间隔类型参数需要有单引号’‘引起来,但是在数据库工具执行中,则不需要单引号’'引起来。
知识延申参考:
SQL Server 日期的加减函数: DATEDIFF DATEADD
DATEDIFF: 返回跨两个指定日期的日期边界数和时间边界数, 语法:
DATEDIFF ( datepart , startdate , enddate ) 用 enddate 减去 startdate,即计算两个日期的间隔值函数: DateDiff(<间隔类型>,<日期 1>,<日期 2>[,W1][,W2])
注:datepart 指定应在日期的哪一部分计算差额的参数,其日期相减时,只关注边界值,例:
SELECT DATEDIFF(YEAR,'2008-12-31','2009-1-1')
结果返回 1
DATEADD : 返回给指定日期加上一个时间间隔后的新 datetime 值。 语法:DATEADD (datepart , number, date )
注: datepart 指定要返回新值的日期的组成部分
number 使用来增加 datepart 的值。正数表示增加,负数表示减少,如果是小数则忽略小数部分,且不做四舍五入。
通过 DATEDIFF 和 DATEADD 的一些日期计算
- 一年的第一天
SELECT DATEADD(YEAR,DATEDIFF(YEAR,0,GETDATE()),0)
注:首先DATEDIFF(YEAR,0,GETDATE()) --计算当前年份与 1900年相差的年数,然后通过计算1900-1-1加上相差的年数的日期即为当年第一天
- 一个季的第一天
SELECT DATEADD(Quarter,DATEDIFF(Quarter,0,GETDATE()),0)
注:首先DATEDIFF(Quarter,0,GETDATE()) --计算当前月份与 1900年相差的季份数,然后通过计算1900-1-1加上相差的季份数的日期即为当季第一天
- 一个月的第一天
SELECT DATEADD(MONTH,DATEDIFF(MONTH,0,GETDATE()),0)
注:首先DATEDIFF(MONTH,0,GETDATE()) --计算当前月份与 1900年相差的月份数,然后通过计算1900-1-1加上相差的月份数的日期即为当月第一天
- 一周的第一天
SELECT DATEADD(wk,DATEDIFF(wk,0,GETDATE()),0)
- 当天的半夜 (00:00:00.000)
SELECT DATEADD(DAY,DATEDIFF(DAY,0,GETDATE()),0)
- 上月的最后一天
SELECT DATEADD(ms,-3,DATEADD(MONTH,DATEDIFF(MONTH,0,GETDATE()),0))
注:用本月的第一天减去3毫秒,即得出上个月的最有一天.SQL SERVER DATETIME类型的时间精确到3毫秒。
- 本月的最后一天
SELECT DATEADD(ms,-3,DATEADD(MONTH,DATEDIFF(MONTH,0,GETDATE())+1,0))
- 本月的天数
i)
SELECT DAY(DATEADD(ms,-3,DATEADD(MONTH,DATEDIFF(MONTH,0,GETDATE())+1,0)))
ii)
SELECT 32-DAY(GETDATE()+(32-DAY(GETDATE())))
- 本年的最后一天
SELECT DATEADD(ms,-3,DATEADD(YEAR,DATEDIFF(YEAR,0,GETDATE())+1,0))
- 一周的第一天
SELECT DATEADD(DAY,1-DATEPART(weekday,GETDATE()),GETDATE())
一周的最后一天
SELECT DATEADD(DAY,7-DATEPART(WeekDay,GETDATE()),GETDATE())
SELECT DATEADD(weekday,DATEDIFF(weekday,0,DATEADD(DAY,6-DATEPART(day,GETDATE()),GETDATE())),0)
日期转换函数 CONVERT CAST
CONVERT 中的 Style. 参数:108 和 114 可以只得到时间。
例
SELECT CONVERT(NVARCHAR(12),GETDATE(),108) ---12:41:15
SELECT CONVERT(NVARCHAR(12),GETDATE(),114) ---12:43:12:590
日期判断函数 ISDATE() 确定输入表达式是否为有效日期。若有效返回 1 否则返回 0 ,返回值为 INT 。
DATEADD日期函数
DATEADD() 函数在日期中添加或减去指定的时间间隔。
日:
在当前日期上加两天
select DATEADD(day,2,'2014-12-30') 2015-01-01
select DATEADD(dd,2,'2014-12-30')
月:
在当前日期上加两个月
select DATEADD(mm,2,'2014-12-30') 结果:2015-02-28
select DATEADD(MONTH,2,'2014-12-30') 结果:2015-02-28
年:
在当前日期上加两年
select DATEADD(yy,2,'2014-12-30') 结果:2016-12-30
select DATEADD(year,2,'2014-12-30') 结果:2016-12-30
语法
DATEADD(datepart,number,date),即日期/时间增加或减少一个时间间隔:DateAdd(<间隔类型>,<间隔值>,<表达式>)
date 参数是合法的日期表达式。number是您希望添加的间隔数;对于未来的时间,此数是正数,对于过去的时间,此数是负数。
datepart 参数可以是下列的值:
datepart 缩写
年 yy, yyyy
季度 qq, q
月 mm, m
年中的日 dy, y
日 dd, d
周 wk, ww
星期 dw, w
小时 hh
分钟 mi, n
秒 ss, s
毫秒 ms
微妙 mcs
纳秒 ns
sql server convert()函数的使用方法
convert函数格式:convert(data_type,expression[,style])
说明:
data_type:目标系统所提供的数据类型,如果转换时没有指定数据类型的长度,则 SQL Server 自动提供长度为 30。
expression:是任何有效的 Microsoft® SQL Server™ 表达式
style:【可选参数】日期格式样式,此样式一般在时间类型(datetime,smalldatetime)与字符串类型(nchar,nvarchar,char,varchar)相互转换的时候才用到
style 参数提供的数值确定了 datetime 数据的显示方式,年份可以显示为两位或四位数。默认情况下,SQL Server 将年份显示为两位数。若要显示包括世纪的四位数年份 (yyyy)(即使年份数据是使用两位数的年份格式存储的),请给 style 值加 100 以获得四位数的年
例子:
1、yyyy-mm-dd hh:mm:ss转为yyyy-mm-dd
Select convert(char(10),getdate(),126);
把2022-12-12 00:00:00.000 转为 2022-12-12
2、yyyy-mm-dd hh:mm:ss.SSS转为yyyy-mm-dd hh:mm:ss
Select convert(char(19),START_TIME_,120);
把 2022-12-12 13:42:35.123 转为 2022-12-12 13:42:35