Dados os seguintes dados:
id | user_id | started | closed | dead
-------------------------------------------------------------------------------------------
7714 | 238846 | 2015-01-27 15:14:50 | 2015-02-02 14:14:13 | NULL
7882 | 238846 | 2015-01-28 13:25:58 | NULL | 2015-05-15 12:16:07
13190 | 259140 | 2015-03-17 10:11:44 | NULL | 2015-03-18 07:31:57
13192 | 259140 | 2015-03-17 10:12:17 | NULL | 2015-03-18 11:46:46
13194 | 259140 | 2015-03-17 10:12:53 | NULL | 2015-03-18 11:46:36
14020 | 259140 | 2015-03-23 14:32:16 | 2015-03-24 15:57:32 | NULL
17124 | 242650 | 2015-04-16 16:19:08 | 2015-04-16 16:21:06 | NULL
19690 | 238846 | 2015-05-15 13:17:31 | NULL | 2015-05-27 13:56:43
20038 | 242650 | 2015-05-19 15:38:17 | NULL | NULL
20040 | 242650 | 2015-05-19 15:39:58 | NULL | 2015-05-21 12:01:02
20302 | 242650 | 2015-05-21 13:09:06 | NULL | NULL
20304 | 242650 | 2015-05-21 13:09:54 | NULL | NULL
20306 | 242650 | 2015-05-21 13:10:19 | NULL | NULL
20308 | 242650 | 2015-05-21 13:12:20 | NULL | NULL
21202 | 238846 | 2015-05-29 16:47:29 | NULL | NULL
21204 | 238846 | 2015-05-29 16:47:56 | NULL | NULL
21208 | 238846 | 2015-05-29 17:05:15 | NULL | NULL
21210 | 238846 | 2015-05-29 17:05:55 | NULL | NULL
21918 | 242650 | 2015-06-04 17:04:29 | NULL | 2015-06-12 15:47:23
Preciso construir um conjunto de dados que atenda às seguintes regras:
- Os grupos são definidos primeiro por
user_id
, então devemos comparar apenas os registros do mesmouser_id
- Todos os registros que começaram pelo menos 15 dias após qualquer outro registro ter sido iniciado, fechado ou morto devem ser contados como grupo.
- De cada grupo, o final deve ser calculado como o primeiro registro fechado ou todos os registros têm um valor para mortos e tomamos a maior data da coluna morta.
- Se um registro não for iniciado dentro de 15 dias após o início ou término de outro grupo, ele iniciará um novo agrupamento.
Provisoriamente, acredito que meus dados devem ficar assim:
usuário_id | começou | fim -------------------------------------------------- ---- 238846 | 27/01/2015 15:14:50 | 2015-02-02 14:14:13 259140 | 23/03/2015 14:32:16 | 2015-03-24 15:57:32 242650 | 16/04/2015 16:19:08 | 16/04/2015 16:21:06 242650 | 21/05/2015 13:09:06 | NULO 238846 | 15/05/2015 13:17:31 | NULO
Alguém pode fornecer algumas orientações sobre como criar uma consulta para atender a essas condições?
Aqui está um link para as instruções DDL e DML para os dados apresentados nesta pergunta.
Como alternativa, poderíamos pular as regras nº 2 e nº 4 e simplesmente declarar que apenas os registros que se sobrepõem devem ser incluídos. A regra mais importante é que, em um determinado conjunto, se houver uma data fechada, ela se tornará o fim do conjunto e não a maior data morta.
Devido à falta de clareza na questão, cheguei a quatro soluções diferentes. As soluções diferem em:
Observe que isso é feito no SQL Server, não no MySQL. Além de algumas alterações de sintaxe muito pequenas, deve funcionar da mesma forma.
Configuração comum e dados de amostra para todos os quatro métodos
1. CASCADING - USANDO A SOLUÇÃO DE REGISTRO FECHADO
Esta é a solução que acredito que o solicitante está procurando e corresponde aos seus resultados.
2. SEM CASCATA - USANDO solução de REGISTRO FECHADO
Início calculado pela primeira data de fechamento quando disponível e, em seguida, pela primeira data de início.
3. SEM CASCATA - USANDO a solução EARLIEST DATE
Início calculado apenas pela data mais antiga.
4. CASCADING - USING EARLIEST DATE solution
Start calculated by earliest date only.
Preocupa-me que não tenhamos uma imagem clara de como um grupo é definido. Digo isso apenas porque, dependendo de algumas condições não declaradas, as datas acima formarão um único grupo gigante ou 3 grupos onde um grupo domina o conjunto.
Faltando condições de agrupamento?
1) Essa regra de 15 dias é cascata? Se um registro
Y
começa 10 dias após outro registroX
e, em seguida, há outro registroZ
iniciado 10 dias depois disso, isso forma um grupo de três registrosX,Y,Z
ou dois grupos, cada um contendo dois registrosX,Y
eY,Z
? Eu fiz a suposição de que as regras de 15 dias se propagam para formar grupos maiores.2) As datas são inclusivas? Por exemplo, se um registro tiver uma data inicial e uma data final muitos meses depois, todos os dias dentro desse intervalo serão mesclados no grupo? Trato ambas as possibilidades em minha análise rápida abaixo.
Agrupamentos potenciais
Portanto, se começarmos com id
7714
, veremos que a data de início é 27/01. Claramente, a próxima entrada7882
começando em 28/01 cai neste grupo. Observe, no entanto, que7882
termina em 15/05, portanto, qualquer coisa que comece dentro de 15 dias a partir de 15/05 deve ser adicionada ao grupo.Assim,
19690
por meio21210
da inclusão no grupo, que por meio de cascata leva à21918
inclusão posterior no grupo. A cascata consumiu quase todas as entradas do conjunto. Chame issoGROUP A
.Se, no entanto, o agrupamento também incluir a data, todas as entradas de
13190
até17124
também devem pertencer aGROUP A
, e agora todos os ids estão em um único grupo.Se as datas de
GROUP A
não forem inclusivas, mas na verdade aderirem estritamente à regra '15 dias depois' com cascata, então, em vez disso, você teria um segundo grupo composto por13190
até14020
, e um terceiro grupo com uma única entrada,17124
.Basicamente, minha pergunta é: algum deles corresponde ao agrupamento pretendido ou há alguma outra informação que está faltando na definição do grupo? Sinto muito por uma resposta tão prolixa, mas não parece que sua saída solicitada provisória atenda à sua definição de agrupamento.
Com esclarecimentos, tenho certeza de que podemos resolver esse problema.