Подсчет результатов по периодам времени дня - PullRequest
3 голосов
/ 26 августа 2011

Предположим, у меня есть таблица типа

CREATE TABLE associacao
(
  id bigserial NOT NULL,
  idusuario character varying(50),
  idunit character varying(50),
  dataassociacao timestamp with time zone,
  codigo bigint NOT NULL DEFAULT 0,
  CONSTRAINT associacao_pkey PRIMARY KEY (id)
)

с данными типа

id | idusuario | idunit | dataassociacao               | codigo
1  | "100000"  | "200"  | "2011-08-25 10:20:25.123-03" |   3
2  | "100000"  | "300"  | "2011-08-25 10:20:25.123-03" |   3
3  | "400000"  | "500"  | "2011-08-25 05:20:26.123-03" |   3
4  | "400000"  | "600"  | "2011-08-25 05:20:26.123-03" |   3
5  | "700000"  | "800"  | "2011-08-25 16:20:26.123-03" |   3
6  | "700000"  | "900"  | "2011-08-25 16:20:26.123-03" |   3
7  | "1000000" | "1100" | "2011-08-25 21:20:26.123-03" |   3
8  | "1200000" | "1300" | "2011-08-24 22:20:23.123-03" |   2
9  | "1200000" | "1300" | "2011-08-24 22:20:26.123-03" |   3

Мне нужен оператор SQL, который делит день на 3 смены (с 22:00 до 00:00 от 06 до 06: 00: 00.000, 06: 00: 00.001–14: 00: 00.000 и 14: 00: 00.001–22: 00: 00.000) и посчитайте, сколько отдельных частей Идузуарио имеет каждая часть.

до сих пор я достигследующий код:

SELECT 
    CASE  
       WHEN DATE_PART('hour', dataassociacao) BETWEEN 6 AND 14 THEN 1 
       WHEN DATE_PART('hour', dataassociacao) BETWEEN 14 AND 22 THEN 2 
       WHEN DATE_PART('hour', dataassociacao) BETWEEN 22 AND 24 THEN 3 
       WHEN DATE_PART('hour', dataassociacao) BETWEEN 0 AND 6 THEN 3
    END AS data, COUNT(distinct idusuario)
FROM associacao
WHERE codigo = 3
GROUP BY data
ORDER BY data;

, который дает мне следующую таблицу (с приведенным выше примером)

data | count(idusuario)
 1   |       1
 2   |       3
 3   |       1

мои проблемы:

  1. , если я хотелподсчет за день, я не могу посчитать смены правильно, например, 3-я смена (ночная смена) будет считаться так, как если бы они работали с 00: 00: 00.001 до 06: 00: 00.000, а затем снова с 22:00:С 00.001 до 00: 00: 00.000 в тот же день, а не с 22: 00: 00.001 накануне до 06: 00: 00.000 текущего дня
  2. дата сравнивает только часы, таким образом, каждая записьс 22: 00: 00.000 до 22: 59: 59,999 рассчитывают на 2-ю смену, а не на 3-ю смену, которая являетсяorrect.

Любые трудности ??

заранее спасибо.

1 Ответ

0 голосов
/ 26 августа 2011

Я думаю, что то, что вы хотите ...

Сначала вам понадобится файл календаря , если у вас его еще нет.

Во-вторых, определите таблицу Shift. Это, вероятно, будет важно для отслеживания в любом случае, и имеет решающее значение здесь. Быстрое и грязное определение:

CREATE TABLE Shift (Shift INTEGER NOT NULL, 
                    Start_Offset SMALLINT NOT NULL,
                    End_Offset SMALLINT NOT NULL,
                    CONSTRAINT Shift_PK PRIMARY KEY(Shift))

Данные для вставки:

INSERT INTO Shift VALUES(1, 6, 14), (2, 14, 22), (3, 22, 30)

Тогда вы сможете выполнить этот запрос:

SELECT a.Calendar_Date, b.Shift, COUNT(DISTINCT c.idusuario)
FROM calendar as a
CROSS JOIN Shift as b
JOIN associacao as c
ON c.dataassociacao >= a.Calendar_Date + ((INTERVAL '1 hours') * b.Start_Offset)
AND c.dataassociacao < a.Calendar_Date + ((INTERVAL '1 hours') * b.End_Offset)
GROUP BY a.Calendar_Date, b.Shift
ORDER BY a.Calendar_Date, b.Shift

В результате:

Calendar_Date    Shift    Count
=======================================
2011-08-24       3        2
2011-08-25       1        1
2011-08-25       2        2 

(Обратите внимание: я выполнил всю работу по сборке / тестированию в DB2, у которой нет функций интервалов. Из просмотра документации и связанной информации в Интернете данный запрос должен быть эквивалентным тому, что Я написал, но не могу проверить на экземпляре PostgreSQL).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...