2016-12-19 3 views
-1

Я следующие запросы в некотором питона коде,Объединения нескольких подобных запросов в 1

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 раза с разными параметрами даты, есть ли способ, которым я мог бы сделать это с 1 запросом, для лучшей производительности?

ответ

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 к < 4-1 (вы имели 3/30 для какая-то причина, но марш заканчивается 3/31)

Раздел 2: 4-1 < 10-1

Раздел 3: 10-1 < 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 обрабатывать работу.

Смежные вопросы