Usuário com melhor resposta
ajuda em query

Pergunta
-
Boa tarde, imaginem a seguinte situação:
1 -tabela tabA(consultas medicas) com as seguintes colunas
pk,pk_medico,pk_utente,inicioConsulta,fimConsulta
2 - tabelaB(registo de gravidezes)
pk,pk_utente,inicio
o que pretendo é o seguinte:
- para determinado ano e mês(passados por parametro), saber o seguinte o total de utentes atendidos por cada medico, tendo em conta o seguinte:
1- se a utente nao estiver gravida, pode ter varias consultas por mes que apenas conta como 1
2- se a utente tiver gravida,tendo como referência a data da 1ª consulta nesse periodo de tempo(ano,mes),caso a proxima consulta seja passados 15 dias é contabilizada.
exemplo 1 :
consulta 1 - 1/04/2014
consulta 2 - 16/04/2014
consulta 3 - 31/04/2014
neste exemplo, conta 3 consultas
exemplo 2 :
consulta 1 - 2/04/2014
consulta 2 - 16/04/2014
consulta 3 - 28/04/2014
neste exemplo, conta 2 consultas( a de 2/04/2014 e a de 16/04/2014)
será que me podiam dar uma ajuda sff?
Respostas
-
Não sei se vai atender a sua necessidade, e mesmo assim talvez existam alternativas melhores, mas experimente fazer um teste com o script abaixo:
declare @TabA table (pk_medico int, pk_utente int, inicioConsulta date); insert into @TabA (pk_medico, pk_utente, inicioConsulta) values (1, 1, '20140301'), (1, 1, '20140316'), (1, 1, '20140331'), (2, 4, '20140302'), (2, 4, '20140316'), (2, 4, '20140328'), (1, 6, '20140301'), (1, 6, '20140314'), (1, 6, '20140327'); declare @ParMes int; declare @ParAno int; set @ParMes = 3; set @ParAno = 2014; declare @DataIni date; declare @DataFim date; set @DataIni = DATEADD(YEAR, @ParAno - 1900, DATEADD(MONTH, @ParMes - 1, 0)); set @DataFim = DATEADD(DAY, -1, DATEADD(MONTH, 1, @DataIni)); with CTE_RN as ( select pk_medico, pk_utente, inicioConsulta, ROW_NUMBER() OVER(PARTITION BY pk_medico, pk_utente ORDER BY inicioConsulta) as RN from @TabA where inicioConsulta between @DataIni and @DataFim ), CTE_Datas as ( select pk_medico, pk_utente, inicioConsulta, RN from CTE_RN where RN = 1 union all select r.pk_medico, r.pk_utente, case when DATEDIFF(DAY, d.inicioConsulta, r.inicioConsulta) < 15 then d.inicioConsulta else r.inicioConsulta end, r.RN from CTE_Datas as d inner join CTE_RN as r on r.pk_medico = d.pk_medico and r.pk_utente = d.pk_utente and r.RN = d.RN + 1 ), CTE_DR as ( select pk_medico, DENSE_RANK() OVER(PARTITION BY pk_medico ORDER BY pk_utente, inicioConsulta) as DR from CTE_Datas ) select pk_medico, MAX(DR) as Qtde from CTE_DR group by pk_medico
Espero que ajude.
Assinatura: http://www.imoveisemexposicao.com.br
- Sugerido como Resposta Giovani Cr terça-feira, 15 de abril de 2014 15:13
- Marcado como Resposta Giovani Cr quinta-feira, 17 de abril de 2014 19:23
Todas as Respostas
-
Boa tarde,
Não sei se vou conseguir ajudar, mas não entendi porque no exemplo 2 devem ser consideradas as consultas de 02/04/2014 e 16/04/2014... Não são somente 14 dias de intervalo? Os intervalos entre 02/04 a 16/04 e 16/04 a 28/04 não possuem a mesma quantidade de dias?
Qual deveria ser o resultado para o exemplo abaixo?
exemplo 3:
consulta 1 - 1/04/2014
consulta 2 - 14/04/2014
consulta 3 - 27/04/2014Assinatura: http://www.imoveisemexposicao.com.br
-
-
Não sei se vai atender a sua necessidade, e mesmo assim talvez existam alternativas melhores, mas experimente fazer um teste com o script abaixo:
declare @TabA table (pk_medico int, pk_utente int, inicioConsulta date); insert into @TabA (pk_medico, pk_utente, inicioConsulta) values (1, 1, '20140301'), (1, 1, '20140316'), (1, 1, '20140331'), (2, 4, '20140302'), (2, 4, '20140316'), (2, 4, '20140328'), (1, 6, '20140301'), (1, 6, '20140314'), (1, 6, '20140327'); declare @ParMes int; declare @ParAno int; set @ParMes = 3; set @ParAno = 2014; declare @DataIni date; declare @DataFim date; set @DataIni = DATEADD(YEAR, @ParAno - 1900, DATEADD(MONTH, @ParMes - 1, 0)); set @DataFim = DATEADD(DAY, -1, DATEADD(MONTH, 1, @DataIni)); with CTE_RN as ( select pk_medico, pk_utente, inicioConsulta, ROW_NUMBER() OVER(PARTITION BY pk_medico, pk_utente ORDER BY inicioConsulta) as RN from @TabA where inicioConsulta between @DataIni and @DataFim ), CTE_Datas as ( select pk_medico, pk_utente, inicioConsulta, RN from CTE_RN where RN = 1 union all select r.pk_medico, r.pk_utente, case when DATEDIFF(DAY, d.inicioConsulta, r.inicioConsulta) < 15 then d.inicioConsulta else r.inicioConsulta end, r.RN from CTE_Datas as d inner join CTE_RN as r on r.pk_medico = d.pk_medico and r.pk_utente = d.pk_utente and r.RN = d.RN + 1 ), CTE_DR as ( select pk_medico, DENSE_RANK() OVER(PARTITION BY pk_medico ORDER BY pk_utente, inicioConsulta) as DR from CTE_Datas ) select pk_medico, MAX(DR) as Qtde from CTE_DR group by pk_medico
Espero que ajude.
Assinatura: http://www.imoveisemexposicao.com.br
- Sugerido como Resposta Giovani Cr terça-feira, 15 de abril de 2014 15:13
- Marcado como Resposta Giovani Cr quinta-feira, 17 de abril de 2014 19:23
-
olá gapimex, obrigado pela ajuda. ainda não testei o seu exemplo, porque não tive tempo.
No entanto, quero complementar uma coisa.
1 - tinha dito que caso o utente nao tivesse gravida, podia ter n consultas no perido de tempo definido para a query que apenas contava uma vez. isso mantêm-se
2 - se estivesse gravida, para que nao haja duvidas o correcto é o seguinte:
consulta 1 - 1/04/2014
consulta 2 - 16/04/2014
consulta 3 - 31/04/2014
neste exemplo, conta 3 consultas
exemplo 2 :
consulta 1 - 2/04/2014
consulta 2 - 16/04/2014
consulta 3 - 28/04/2014
no exemplo 2 conta 2 consultas, consultas 1 e 3. porque a ideia é, a partir de uma consulta considerada, que conta, vamos ter que contabilizar a proxima apos um periodo de 15 dias
exemplo 3:
consulta 1 - 1/04/2014
consulta 2 - 14/04/2014
consulta 3 - 27/04/2014
conta apenas as consultas dos dias 1 e 27.
exemplo 4:
consulta 1 - 1/04/2014
consulta 2 - 8/04/2014
consulta 3 - 18/04/2014
consulta 4 - 25/04/2014
no exemplo 4, conta as consultas do dia 1 e dia 18.