我在一些python代码中有以下查询,
sel = select([staff.c.name,
staff.c.start_date,
staff.c.leave_allowance,
]) \
.select_from(staff) \
.where(staff.c.name == request.args.get('user')) \
.group_by(staff.c.name, staff.c.leave_allowance, staff.c.start_date)
staff_member = ZS.db_connect().execute(sel).fetchone()
staff_member = dict(staff_member)
sel1 = select([staff.c.start_date,
func.sum(leave.c.hours).label('hours_taken')
]) \
.select_from(join(staff, leave, (staff.c.name == leave.c.name))) \
.where(leave.c.leave_start >= '2016-01-01') \
.where(leave.c.leave_end <= '2016-03-30') \
.where(leave.c.hr_status == 'RP_Approved') \
.where(leave.c.name == request.args.get('user')) \
.group_by(staff.c.name, staff.c.start_date)
jan_user = ZS.db_connect().execute(sel1).fetchone()
if(jan_user):
jan_user = dict(jan_user)
staff_member['JanMarTaken'] = jan_user['hours_taken']
else:
staff_member['JanMarTaken'] = 0
sel2 = select([staff.c.start_date,
func.sum(leave.c.hours).label('hours_taken')
]) \
.select_from(join(staff, leave, (staff.c.name == leave.c.name))) \
.where(leave.c.leave_start >= '2016-04-01') \
.where(leave.c.leave_end <= '2016-09-30') \
.where(leave.c.hr_status == 'RP_Approved') \
.where(leave.c.name == request.args.get('user')) \
.group_by(staff.c.name, staff.c.start_date)
mar_user = ZS.db_connect().execute(sel2).fetchone()
if(mar_user):
mar_user = dict(mar_user)
staff_member['MarSeptHours'] = mar_user['hours_taken']
else:
staff_member['MarSeptHours'] = 0
sel2 = select([staff.c.start_date,
func.sum(leave.c.hours).label('hours_taken')
]) \
.select_from(join(staff, leave, (staff.c.name == leave.c.name))) \
.where(leave.c.leave_start >= '2016-10-01') \
.where(leave.c.leave_end <= '2016-12-31') \
.where(leave.c.hr_status == 'RP_Approved') \
.where(leave.c.name == request.args.get('user')) \
.group_by(staff.c.name, staff.c.start_date)
oct_user = ZS.db_connect().execute(sel2).fetchone()
if(oct_user):
mar_user = dict(mar_user)
staff_member['OctDecHours'] = mar_user['hours_taken']
else:
staff_member['OctDecHours'] = 0
查询都基本上做同样的事情,即按名称搜索用户并检索某些日期之间记录的一些数据,我需要一年中3段的数据,所以目前我查询数据库3次使用不同的日期参数,有一种方法可以通过1个查询执行此操作,以获得更好的性能吗?
答案 0 :(得分:0)
在SQL中执行此操作,以便您可以转换为存储过程,我在报告年度添加了一个变量@YearToCheck来传递。
让我们制作一些测试数据:
DECLARE @Staff TABLE
(
Name VARCHAR(100),
Emp_Start_Date DATETIME,
Emp_End_Date DATETIME,
Emp_Leave_Allowance INT
)
DECLARE @Leave TABLE
(
Name VARCHAR(100),
Leave_Start DATETIME,
Leave_End DATETIME,
Hr_Status VARCHAR(100)
)
DECLARE @YearToCheck INT = 2016
INSERT INTO @Staff
( Name, Emp_Start_Date, Emp_End_Date, Emp_Leave_Allowance )
VALUES
( 'Fred', DATEFROMPARTS( 2016, 1, 3 ), NULL, 10 ),
( 'Wilma', DATEFROMPARTS( 2014, 2, 1 ), NULL, 10 ),
( 'Barney', DATEFROMPARTS( 2015, 7, 1 ), NULL, 10 ),
( 'Betty', DATEFROMPARTS( 2014, 2, 1 ), NULL, 10 );
INSERT INTO @Leave
( Name, Leave_Start, Leave_End, Hr_Status )
VALUES
( 'Fred', DATEFROMPARTS( 2015, 12, 1), DATEFROMPARTS( 2016, 6, 1), 'RP_Approved'),
( 'Fred', DATEFROMPARTS( 2016, 7, 1), DATEFROMPARTS( 2016, 8, 1), 'RP_Approved'),
( 'Wilma', DATEFROMPARTS( 2016, 1, 10), DATEFROMPARTS( 2016, 1, 15), 'RP_Approved'),
( 'Barney', DATEFROMPARTS( 2016, 6, 10), DATEFROMPARTS( 2016, 7, 10), 'RP_Approved'),
( 'Betty', DATEFROMPARTS( 2016, 7, 30), DATEFROMPARTS( 2016, 8, 5), 'RP_Approved'),
( 'Betty', DATEFROMPARTS( 2016, 9, 29), DATEFROMPARTS( 2016, 10, 3), 'RP_Approved'),
( 'Betty', DATEFROMPARTS( 2015, 1, 1), DATEFROMPARTS( 2017, 1, 5), 'RP_Approved');
现在让我们运行一个查询来查找不同的日期分区
第1节:1-1至&lt; 4-1(由于某种原因你有3/30,但3月31日结束了?)
第2节:4-1至&lt; 10-1
第3节:10-1至&lt; 1-1(明年)
SELECT s.Name,
CASE WHEN (l.Leave_Start <= DATEFROMPARTS( @YearToCheck, 4, 1)) AND (DATEFROMPARTS( @YearToCheck, 1, 1) <= l.Leave_End)
THEN
DATEDIFF( DAY,
CASE WHEN l.Leave_Start < DATEFROMPARTS( @YearToCheck, 1, 1) THEN DATEFROMPARTS( @YearToCheck, 1, 1) ELSE l.Leave_Start END,
CASE WHEN l.Leave_End > DATEFROMPARTS( @YearToCheck, 4, 1) THEN DATEFROMPARTS( @YearToCheck, 4, 1) ELSE DATEADD(DAY, 1, l.Leave_End) END ) --Inclusive
ELSE 0
END AS FirstSection,
CASE WHEN (l.Leave_Start <= DATEFROMPARTS( @YearToCheck, 10, 1)) AND (DATEFROMPARTS( @YearToCheck, 4, 1) <= l.Leave_End)
THEN
DATEDIFF( DAY,
CASE WHEN l.Leave_Start < DATEFROMPARTS( @YearToCheck, 4, 1) THEN DATEFROMPARTS( @YearToCheck, 4, 1) ELSE l.Leave_Start END,
CASE WHEN l.Leave_End > DATEFROMPARTS( @YearToCheck, 10, 1) THEN DATEFROMPARTS( @YearToCheck, 10, 1) ELSE DATEADD(DAY, 1, l.Leave_End) END ) --Inclusive
ELSE 0
END AS SecondSection,
CASE WHEN (l.Leave_Start <= DATEFROMPARTS( @YearToCheck + 1, 1, 1)) AND (DATEFROMPARTS( @YearToCheck, 10, 1) <= l.Leave_End)
THEN
DATEDIFF( DAY,
CASE WHEN l.Leave_Start < DATEFROMPARTS( @YearToCheck, 10, 1) THEN DATEFROMPARTS( @YearToCheck, 10, 1) ELSE l.Leave_Start END,
CASE WHEN l.Leave_End > DATEFROMPARTS( @YearToCheck + 1, 1, 1) THEN DATEFROMPARTS( @YearToCheck + 1, 1, 1) ELSE DATEADD(DAY, 1, l.Leave_End) END ) --Inclusive
ELSE 0
END AS ThirdSection
FROM @Staff s
INNER JOIN @Leave l
ON l.Name = s.Name
WHERE l.Hr_Status = 'RP_Approved'
以下是天数的输出数据:
Name FirstSection SecondSection ThirdSection
Fred 91 62 0
Fred 0 32 0
Wilma 6 0 0
Barney 0 31 0
Betty 0 7 0
Betty 0 2 3
Betty 91 183 92
现在,我不会检查假期范围是否重叠,或者周日是否重叠等等......因为问题中没有,可以添加,但希望这是你可以使用从python中拉出逻辑并让sql server处理工作。