2015-03-12 14 views
0

Не удалось найти вопросы, соответствующие моей. Если вы знаете, пожалуйста, дайте мне знать.Как суммировать зарегистрированные часы между двумя датами (не только общее количество часов между двумя датами)

Мне нужен оператор выбора, который показывает мне общее количество часов для сотрудника между датами.

Пример:

Сотрудник Dennis имел отсутствие от 2014-06-10 до 2014-06-13. У этого сотрудника были разные часы отсутствия между датами. Допустим, что Деннис уже отсутствовал так:

2014-06-10: 477 minutes 
2014-06-11: 498 minutes 
2014-06-12: 491 minutes 
2014-06-13: 397 minutes 
total absence: 1863 minutes 

Я хочу, чтобы получить результат, как это:

У меня есть таблицы
EmployeeTime, которые имеют часы отсутствия в день.
AbsenseDays которые имеют от и до даты для отсутствия.

EmployeeTime будет выглядеть следующим образом:

| EmployeeName | Date | RegisteredHour | 

и AbsenceDays будет выглядеть следующим образом:

| FromDate | TillDate | AbsenceId | KeyNo | 

У меня есть третий стол LogTable, который может связать эти две таблицы вместе KeyNo и EmployeeID ,

Выход я получаю:

| EmployeeName | FromDate | TillDate | Days |Days without weekends | Date  | RegisteredHour | Total min absence 
| Dennis  | 2014-06-10 | 2014-06-13 | 4 |  4    | 2014-06-10 | 477   | 9540 
| Dennis  | 2014-06-10 | 2014-06-13 | 4 |  4    | 2014-06-11 | 498   | 9960 
| Dennis  | 2014-06-10 | 2014-06-13 | 4 |  4    | 2014-06-12 | 491   | 9960 
| Dennis  | 2014-06-10 | 2014-06-13 | 4 |  4    | 2014-06-13 | 397   | 7940 
| Joanne  | 2014-05-09 | 2014-05-12 | 4 |  2    | 2014-05-09 | 420   | 2100 
| Joanne  | 2014-05-09 | 2014-05-12 | 4 |  2    | 2014-05-10 | 0    | 0 
| Joanne  | 2014-05-09 | 2014-05-12 | 4 |  2    | 2014-05-11 | 0    | 0 
| Joanne  | 2014-05-09 | 2014-05-12 | 4 |  2    | 2014-05-12 | 450   | 2250 

Мне нужно, чтобы получить этот результат:

| EmployeeName | FromDate | TillDate | Days |Days without weekends | Total min absence 
| Dennis  | 2014-06-10 | 2014-06-13 | 4 |  4    | 1863 
| Joanne  | 2014-06-09 | 2014-06-12 | 4 |  2    | 870 

Мой код:

SELECT DISTINCT 
    EmployeeTime.Name, 
    CONVERT(VARCHAR(10),FromDate,20) FromDate, 
    CONVERT(VARCHAR(10),Tilldate,20) Tilldate, 
    (DATEDIFF(DD, FromDate, Tilldate) +1) TotalDays, 
    (DATEDIFF(DD, FromDate, Tilldate) +1) - (DATEDIFF(wk, FromDate, Tilldate) * 2) DaysMinusWeekends, 
    CONVERT(VARCHAR(10),Dato,105) DateDato, 
    RegisteredHour, 
    SUM(RegisteredHour) Total 
FROM EmployeeTime, AbsenceDays, LogTable 
WHERE EmployeeTime.EmployeeId = LogTable.EmployeeId 
    AND LogTable.KeyNo = AbsenceDays.KeyNo 
    AND EmployeeTime.EmployeeId = 'D994' 
    AND (DATEDIFF(DD, FromDate, TillDate) +1) = 4 
    AND CONVERT(VARCHAR(10),FromDate,20) <= CONVERT(VARCHAR(10),Dato,20) 
    AND CONVERT(VARCHAR(10),TillDate,20) >= CONVERT(VARCHAR(10),Dato,20) 
    GROUP BY EmployeeTime.EmployeeId,FromDate, TillDate, Dato, RegisteredHour 
    ORDER BY EmployeeTime.EmployeeId 

Примечание: Мне нужен ответ, где дон 'self-join tables или использовать WITH-запросы; SELECT должен быть первым в SQL, или программа не поймет его.

+0

Я попытался сделать это более читаемым, но есть некоторые вещи, которые я не понимаю. Было бы полезно, если бы вы могли показать полное определение ('CREATE TABLE ...') для всех задействованных таблиц. Было бы также полезно, если бы вы могли уточнить, что вы подразумеваете под «Мне нужен ответ, где вы не присоединяетесь к таблицам» - SELECT, который вы показываете *, * присоединяется к таблицам, и ваша схема выглядит так, что это невозможно сделать без соединение. – zwol

+0

Спасибо, что я вернулся завтра, поэтому я просто сделал быстрое редактирование! – marinadelademad

ответ

0

Это мое лучшее предположение в ответ. Вероятно, он не будет работать как есть для вас, потому что: (1) я не знаю полную схему таблицы для всех ваших таблиц; (2) Я не понимаю, что вы подразумеваете под «Мне нужен ответ, где вы не присоединяетесь к столам»; (3) Я знаю только PostgreSQL, а не SQL Server.

В английском языке, что вы хотите сделать, это выбрать строку из AbsenceDays, а затем использовать FromDate и TillDate для выбора набора строк в EmployeeTime, а затем просуммировать RegisteredHour колонки в тех, а не разница в абсолютной дате , Самый очевидный способ сделать это

SELECT et.EmployeeName, ad.FromDate, ad.TillDate, SUM(et.RegisteredHour) 

    FROM LogTable lt 
    JOIN EmployeeTime et ON lt.EmployeeId = et.EmployeeId 
    JOIN AbsenceDays ad ON lt.KeyNo  = ad.KeyNo 

WHERE et.Date >= ad.FromDate 
    AND et.Date <= ad.TillDate 
-- AND et.EmployeeName = 'Dennis' 

GROUP BY et.EmployeeName, ad.FromDate, ad.TillDate 
ORDER BY et.EmployeeName, ad.FromDate; 

Оглядываясь на свой код, кажется, что у вас есть по существу это встроенный там, но затемненный с большим количеством новообращенных и DATEDIFFs, которые кажутся ненужными мне. Возможно, это связано с тем, что я снова знаю PostgreSQL. Я рекомендую вам разбить код до минимального минимума, например, и затем добавить конверсии обратно до тех пор, пока база данных не примет его.

Другая потенциальная проблема заключается в том, что (EmployeeName, FromDate, TillDate) однозначно не идентифицирует одно непрерывное отсутствие. (Кажется, у вас есть два столбца ID в AbsenceDays, что говорит о том, что это может быть проблемой.) Также вы говорите непоследовательно минут и часов, поэтому я не знаю, чего вы действительно хотите. И, наконец, у меня есть нет идеи, как вычислить количество дней вне недели.

+0

Благодарим вас за ответ. RegisteredHour - это минуты в db, но в программе на моей работе они показывают часы и минуты. Преобразование, которое я делаю, связано с тем, что даты, которые я получаю, это минуты, а минуты из et.Date не совсем такие же, как в минутах от ad.from- и tilldates. Я конвертирую их, поэтому я сравниваю их только по yyyy-mm-dd. Я сделал ваш пример, но сумма зарегистрированных часов не имеет смысла для меня: у Тони есть три дня отсутствия с 450 минутами в день. Это должно дать 1350, но SUM (et.RegisteredHour) дает 3600. – marinadelademad

+0

Я не думаю, что смогу помочь вам в дальнейшей информации. В значениях в RegisteredHour должно быть что-то странное. Прочтите https://stackoverflow.com/help/how-to-ask и https://stackoverflow.com/help/mcve и, используя этот совет, задайте новый вопрос. Также вам может быть повезло на http://dba.stackexchange.com/ – zwol

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