2015-04-08 1 views
1

Этот код работает отлично, но время выполнения занимает много времени, потому что attendance_03 имеет то же количество строк, что и working_schedule_03, которым действительно нужны каждая строка, потому что working_schedule_03 имеют график сдвига например, 8:00, 9:00 и т. д., и именно здесь attendance_03 основывает своих покойных сотрудников, attendance_03 имеют фактическое время для сотрудника, теперь я хочу группировать некоторые значения в нескольких столбцах в таблице , которая равна emp_id. и t_in (сдвиг графика), потому что t_in не фиксирован, сотрудники меняют расписание каждую неделю, а другие имеют фиксированный график и последний столбец eve, которые имеют значение «Обычный» и разгруппируют значения «День отдыха», поэтому attendance_03 не получит строки из столбца eve, которые имеют значения дня отдыха. благодаря!Группа По определенному значению в столбце для более быстрого выполнения - SQL

SELECT 
    a.emp_id, COUNT(a.a_id) AS Cymon, b.t_in AS mt_in, c.last_name, c.first_name, e.dept_name, e.dept_id, f.l_id, f.loc 
FROM 
    attendance_03 AS a 
    LEFT JOIN 
     (SELECT * FROM working_schedule_03 WHERE d BETWEEN 16 AND 31 AND Y = 2015 AND eve="Regular") AS b ON b.emp_id = a.emp_id AND b.d = a.dd 
    LEFT JOIN 
     employee_personal_info AS c ON c.emp_id = a.emp_id 
    LEFT JOIN 
     employee_information AS d ON d.emp_id = a.emp_id 
    LEFT JOIN 
     departments AS e ON e.dept_id = d.department 
    LEFT JOIN 
     employee_location AS f ON f.l_id = d.loc 
    WHERE a.yy = 2015 AND a.dd BETWEEN 16 AND 31 AND b.eve = "Regular" AND e.dept_id != 22 
     AND 
    CASE 
    WHEN b.t_in = "07:00" THEN HOUR(a.t_in) = "07" AND MINUTE(a.t_in) BETWEEN 01 AND 59 
    WHEN b.t_in = "07:30" THEN HOUR(a.t_in) = "07" AND MINUTE(a.t_in) BETWEEN 31 AND 59 OR HOUR(a.t_in) = "08" AND MINUTE(a.t_in) BETWEEN 01 AND 30 
    WHEN b.t_in = "08:00" THEN HOUR(a.t_in) = "08" AND MINUTE(a.t_in) BETWEEN 01 AND 59 
    WHEN b.t_in = "08:30" THEN HOUR(a.t_in) = "08" AND MINUTE(a.t_in) BETWEEN 31 AND 59 OR HOUR(a.t_in) = "09" AND MINUTE(a.t_in) BETWEEN 01 AND 30 
    WHEN b.t_in = "09:00" THEN HOUR(a.t_in) = "09" AND MINUTE(a.t_in) BETWEEN 01 AND 59 
    WHEN b.t_in = "10:00" THEN HOUR(a.t_in) = "10" AND MINUTE(a.t_in) BETWEEN 01 AND 59 
    WHEN b.t_in = "13:00" THEN HOUR(a.t_in) = "13" AND MINUTE(a.t_in) BETWEEN 01 AND 59 
    WHEN b.t_in = "15:00" THEN HOUR(a.t_in) = "15" AND MINUTE(a.t_in) BETWEEN 01 AND 59 
    WHEN b.t_in = "16:00" THEN HOUR(a.t_in) = "16" AND MINUTE(a.t_in) BETWEEN 01 AND 59 
    WHEN b.t_in = "17:00" THEN HOUR(a.t_in) = "17" AND MINUTE(a.t_in) BETWEEN 01 AND 59 
    WHEN b.t_in = "19:00" THEN HOUR(a.t_in) = "19" AND MINUTE(a.t_in) BETWEEN 01 AND 59 
    WHEN b.t_in = "19:30" THEN HOUR(a.t_in) = "19" AND MINUTE(a.t_in) BETWEEN 31 AND 59 OR HOUR(a.t_in) = "20" AND MINUTE(a.t_in) BETWEEN 01 AND 30 
    WHEN b.t_in = "20:00" THEN HOUR(a.t_in) = "20" AND MINUTE(a.t_in) BETWEEN 01 AND 59 
    WHEN b.t_in = "21:00" THEN HOUR(a.t_in) = "21" AND MINUTE(a.t_in) BETWEEN 01 AND 59 
    WHEN b.t_in = "23:45" THEN HOUR(a.t_in) = "23" AND MINUTE(a.t_in) BETWEEN 46 AND 59 OR HOUR(a.t_in) = "20" AND MINUTE(a.t_in) BETWEEN 01 AND 45 
    ELSE 0 END 
    GROUP BY a.emp_id 
    HAVING COUNT(a.emp_id) > 1 
    ORDER BY f.loc, e.dept_id, c.last_name ASC 

working_schedule_03 стол

CREATE TABLE `working_schedule_03` (
    `id` mediumint(99) NOT NULL AUTO_INCREMENT, 
    `start_date` datetime NOT NULL, 
    `end_date` datetime NOT NULL, 
    `username` varchar(255) NOT NULL, 
    `m` varchar(9) NOT NULL, 
    `d` varchar(9) NOT NULL, 
    `y` varchar(9) NOT NULL, 
    `emp_id` varchar(99) NOT NULL, 
    `eve` varchar(99) NOT NULL, 
    `t_in` varchar(99) NOT NULL, 
    `t_out` varchar(99) NOT NULL, 
    `emp_file` varchar(99) NOT NULL, 
    `dt_plot` varchar(99) NOT NULL, 
    PRIMARY KEY (`id`) 
) ENGINE=MyISAM AUTO_INCREMENT=612993 DEFAULT CHARSET=latin1 

attendance_03 стол

CREATE TABLE `attendance_03` (
    `a_id` varchar(99) NOT NULL, 
    `t_in` varchar(99) NOT NULL, 
    `t_b1_out` varchar(99) NOT NULL, 
    `t_b1_in` varchar(99) NOT NULL, 
    `t_lb_out` varchar(99) NOT NULL, 
    `t_lb_in` varchar(99) NOT NULL, 
    `t_b2_out` varchar(99) NOT NULL, 
    `t_b2_in` varchar(99) NOT NULL, 
    `t_out` varchar(99) NOT NULL, 
    `mu` varchar(99) NOT NULL, 
    `status` varchar(99) NOT NULL, 
    `mm` varchar(99) NOT NULL, 
    `dd` varchar(99) NOT NULL, 
    `yy` varchar(99) NOT NULL, 
    `d_out` int(2) NOT NULL, 
    `d_b1_out` int(2) NOT NULL, 
    `d_b1_in` int(2) NOT NULL, 
    `d_lb_out` int(2) NOT NULL, 
    `d_lb_in` int(2) NOT NULL, 
    `d_b2_out` int(2) NOT NULL, 
    `d_b2_in` int(2) NOT NULL, 
    `emp_id` varchar(99) NOT NULL 
) ENGINE=MyISAM DEFAULT CHARSET=latin1 
+0

Не помещайте продукты, не участвующие. Используете ли вы как MS SQL Server, так и MySQL? – jarlh

+0

У вас есть решение для этого? – mcci

+0

Нет, но я нахожу некоторые странные вещи. 1) если у вас есть внешние условия таблицы в предложении where, это внешнее соединение работает как регулярное внутреннее соединение. 2) Общая группа по правилу говорит: «Если указано предложение GROUP BY, каждая ссылка столбца в списке SELECT должна либо идентифицировать столбец группировки, либо быть аргументом функции набора». – jarlh

ответ

1

Добавление индексов ускорит его значительно:

  • working_schedule_03 бы Bene от INDEX(Y, d, eve).
  • attendance_03 выиграл бы от INDEX(emp_id, dd).
  • employee_personal_info и employee_information: INDEX(emp_id).
  • departments: INDEX(e.dept_id)
  • employee_location: INDEX(f.l_id)

Избавьтесь от LEFT, если вы не ожидать 'право' таблицы отсутствующим совпадающие строки.

Второе появление AND b.eve = "Regular" является избыточным (из-за первого).

Подзапрос сообщает SELECT *. Было бы не так много вещей, чтобы вытащить их, если вы указали только необходимые значения (emp_id, t_in, d).

я кляп на другие вещи:

  • Не используйте VARCHAR для чисел.
  • Рассмотрите возможность использования TIME для раз. (Но может быть проблема с :00 секунд.)
  • Большой CASE мог почти быть превращен в

    a.t_in> = b.t_in И a.in < b.t_in + ИНТЕРВАЛ 60 МИНУТ

  • Проверьте выход; COUNT(...) может иметь большее значение, чем необходимо.

+0

это какая-то большая информация, которая оптимизирует мой SQL-запрос и минимизирует время его выполнения, я не создал таблицу, которую кто-то сделал, я только одна развивающая система из нее, так что ... я тот, , могу ли я изменить изменение структуры столбцов, если есть миллионы записей? – mcci

+0

См. 'ALTER TABLE', как изменить структуру существующей таблицы. Но обратите внимание, что это заблокирует таблицу в течение некоторого времени. –

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