AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • Início
  • system&network
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • Início
  • system&network
    • Recentes
    • Highest score
    • tags
  • Ubuntu
    • Recentes
    • Highest score
    • tags
  • Unix
    • Recentes
    • tags
  • DBA
    • Recentes
    • tags
  • Computer
    • Recentes
    • tags
  • Coding
    • Recentes
    • tags
Início / dba / Perguntas / 270142
Accepted
Juan Velez
Juan Velez
Asked: 2020-07-01 07:43:21 +0800 CST2020-07-01 07:43:21 +0800 CST 2020-07-01 07:43:21 +0800 CST

Derivar períodos de datas de datas de início e término na tabela do SQL Server

  • 772

Estou usando o SQL Server 2016

Eu tenho uma tabela que contém 1 linha por mês que um paciente é atribuído a um determinado provedor.

Um paciente pode ser atribuído a vários provedores durante o ano.

Como posso derivar intervalos de datas (data de início e data de término) para representar a hora em que um paciente foi atribuído a cada provedor.

Minha tabela está assim:

+----------+---------------+------------+-----------+
| Provider | Patient       | StartDate  | EndDate  | 
+----------+---------------+------------+-----------+
| 1922157  | 12345         | 20191201  | 20191231 | 
| 1904176  | 12345         | 20191101  | 20191201 |
| 1904176  | 12345         | 20191001  | 20191101 |
| 1904176  | 12345         | 20190901  | 20191001 | 
| 1904176  | 12345         | 20190801  | 20190901 |
| 1904176  | 12345         | 20190701  | 20190801 |
| 1904176  | 12345         | 20190601  | 20190701 |
| 1904176  | 12345         | 20190501  | 20190601 |
| 1904176  | 12345         | 20190401  | 20190501 |
| 1904176  | 12345         | 20190301  | 20190401 |
| 1904176  | 12345         | 20190201  | 20190301 |
| 1922157  | 12345         | 20190101  | 20190201 |
| 1922157  | 56789         | 20190101  | 20190201 |
+----------+---------------+------------+-----------+

Neste caso, o paciente 12345 foi atribuído a 2 provedores diferentes. Um para 2 meses, janeiro e dezembro e outro para o resto do ano (10 meses) de fevereiro a novembro. O paciente 56789 foi atribuído apenas a 1 provedor (1922157) por 1 mês (em dezembro).

Estou tentando fazer com que minha saída se pareça com a tabela abaixo, mas estou tendo problemas, acho que porque o paciente é atribuído ao mesmo pcp durante 2 épocas diferentes do ano. Tentei usar a função lag, mas só obtenho os resultados corretos em alguns casos, mas não em todos, como neste caso em particular.

+----------+---------------+------------+-----------+
| Provider | Patient       | StartDate  | EndDate  | 
+----------+---------------+------------+-----------+
| 1922157  | 12345         | 20190101  | 20190201  | 
| 1904176  | 12345         | 20190201  | 20191201  | 
| 1922157  | 12345         | 20191201  | 20191231  | 
| 1922157  | 56789         | 20191201  | 20191231  |
+----------+---------------+------------+-----------+

Atualização: estava fazendo mais algumas pesquisas e me deparei com o seguinte post:

https://stackoverflow.com/questions/35900765/ms-sql-combine-date-rows-into-start-end-date

Acabei de encaixar minha tabela no código na resposta para a pergunta acima e testei alguns dos meus casos e parece que pode fazer o trabalho. Infelizmente, minha tabela base tem 140 mil linhas de datas que precisarão ser calculadas, então não tenho certeza de quanto tempo levará para ser executada. Está funcionando agora por 6 minutos, vou postar de volta com os resultados.

sql-server date-math
  • 1 1 respostas
  • 188 Views

1 respostas

  • Voted
  1. Best Answer
    Danielle Paquette-Harvey
    2020-07-01T09:45:27+08:002020-07-01T09:45:27+08:00

    Acho que entendi o que você está tentando fazer. Você está tentando obter a data de início e a data de término de um paciente em um provedor, desde que não haja intervalo entre as datas de início e término dos períodos. Criei uma tabela de teste com os dados amostrados.

    Create table test (Provider int, Patient int, startdate date, enddate date)
    insert into test (Provider, Patient, StartDate, EndDate)
    
    SELECT * FROM 
    (SELECT 1922157 as Provider  , 12345 as Patient         , '2019-12-01' as StartDate , '2019-12-31' as EndDate
    union all SELECT 1904176  , 12345         , '2019-11-01'  , '2019-12-01' 
    union all SELECT 1904176  , 12345         , '2019-10-01'  , '2019-11-01' 
    union all SELECT 1904176  , 12345         , '2019-09-01'  , '2019-10-01' 
    union all SELECT 1904176  , 12345         , '2019-08-01'  , '2019-09-01' 
    union all SELECT 1904176  , 12345         , '2019-07-01'  , '2019-08-01' 
    union all SELECT 1904176  , 12345         , '2019-06-01'  , '2019-07-01' 
    union all SELECT 1904176  , 12345         , '2019-05-01'  , '2019-06-01' 
    union all SELECT 1904176  , 12345         , '2019-04-01'  , '2019-05-01' 
    union all SELECT 1904176  , 12345         , '2019-03-01'  , '2019-04-01' 
    union all SELECT 1904176  , 12345         , '2019-02-01'  , '2019-03-01' 
    union all SELECT 1922157  , 12345         , '2019-01-01'  , '2019-02-01' 
    union all SELECT 1922157  , 56789         , '2019-01-01'  , '2019-02-01' )t
    

    A ideia é começar por ordenar os dados e tentar obter os que coincidem com as datas de início e de fim, de forma a detectar um furo nas datas. Eu faço isso com a função "ROW_NUMBER". Em seguida, encontro todas as linhas que correspondem e pego o primeiro StartDate e max EndDate para aqueles que correspondem e, em seguida, adiciono todas as linhas que estão "sozinhas" e não têm correspondência.

    Eu acho que funciona com os dados que você forneceu. Não consegui testar com outros dados. A recursividade é outra opção para encontrar as datas Min/Max de valores diferentes, mas não usei recursividade neste caso. (fique à vontade para dar nomes melhores, fui um pouco rápido)

    ;With RowsWithNum AS
    (
    SELECT Provider, Patient, StartDate, EndDate, ROW_NUMBER() OVER (ORDER BY Provider, patient, StartDate) as RowNum
    FROM test
    )
    ,BeforeAndAfterDates AS
    (
    SELECT a.Provider, a.Patient, a.StartDate, a.RowNum, a.EndDate, b.StartDate EndStartDate, DATEPART(DAYOFYEAR, b.StartDate)-DATEPART(DAYOFYEAR,a.EndDate) as DateDiffInDays, b.EndDate as EndEndDate, b.RowNum as EndRowNum
    FROM RowsWithNum a
    LEFT JOIN RowsWithNum b ON b.Provider=a.Provider and b.Patient=a.Patient and b.StartDate=a.EndDate
    )
    SELECT Provider, Patient, Min(StartDate) as StartDate, Max(EndEndDate) as EndDate, Min(RowNum) as RowNum
    FROM BeforeAndAfterDates
    WHERE DateDiffInDays=0
    GROUP BY Provider, Patient
    UNION
    SELECT a.Provider, a.Patient, a.StartDate, a.EndDate, a.RowNum
    FROM BeforeAndAfterDates a
    LEFT JOIN BeforeAndAfterDates b ON b.EndEndDate=a.enddate
    WHERE a.DateDiffInDays IS NULL AND b.RowNum IS NULL
    

    E aqui está o meu resultado.

    resultado

    • 0

relate perguntas

  • SQL Server - Como as páginas de dados são armazenadas ao usar um índice clusterizado

  • Preciso de índices separados para cada tipo de consulta ou um índice de várias colunas funcionará?

  • Quando devo usar uma restrição exclusiva em vez de um índice exclusivo?

  • Quais são as principais causas de deadlocks e podem ser evitadas?

  • Como determinar se um Índice é necessário ou necessário

Sidebar

Stats

  • Perguntas 205573
  • respostas 270741
  • best respostas 135370
  • utilizador 68524
  • Highest score
  • respostas
  • Marko Smith

    conectar ao servidor PostgreSQL: FATAL: nenhuma entrada pg_hba.conf para o host

    • 12 respostas
  • Marko Smith

    Como fazer a saída do sqlplus aparecer em uma linha?

    • 3 respostas
  • Marko Smith

    Selecione qual tem data máxima ou data mais recente

    • 3 respostas
  • Marko Smith

    Como faço para listar todos os esquemas no PostgreSQL?

    • 4 respostas
  • Marko Smith

    Listar todas as colunas de uma tabela especificada

    • 5 respostas
  • Marko Smith

    Como usar o sqlplus para se conectar a um banco de dados Oracle localizado em outro host sem modificar meu próprio tnsnames.ora

    • 4 respostas
  • Marko Smith

    Como você mysqldump tabela (s) específica (s)?

    • 4 respostas
  • Marko Smith

    Listar os privilégios do banco de dados usando o psql

    • 10 respostas
  • Marko Smith

    Como inserir valores em uma tabela de uma consulta de seleção no PostgreSQL?

    • 4 respostas
  • Marko Smith

    Como faço para listar todos os bancos de dados e tabelas usando o psql?

    • 7 respostas
  • Martin Hope
    Jin conectar ao servidor PostgreSQL: FATAL: nenhuma entrada pg_hba.conf para o host 2014-12-02 02:54:58 +0800 CST
  • Martin Hope
    Stéphane Como faço para listar todos os esquemas no PostgreSQL? 2013-04-16 11:19:16 +0800 CST
  • Martin Hope
    Mike Walsh Por que o log de transações continua crescendo ou fica sem espaço? 2012-12-05 18:11:22 +0800 CST
  • Martin Hope
    Stephane Rolland Listar todas as colunas de uma tabela especificada 2012-08-14 04:44:44 +0800 CST
  • Martin Hope
    haxney O MySQL pode realizar consultas razoavelmente em bilhões de linhas? 2012-07-03 11:36:13 +0800 CST
  • Martin Hope
    qazwsx Como posso monitorar o andamento de uma importação de um arquivo .sql grande? 2012-05-03 08:54:41 +0800 CST
  • Martin Hope
    markdorison Como você mysqldump tabela (s) específica (s)? 2011-12-17 12:39:37 +0800 CST
  • Martin Hope
    Jonas Como posso cronometrar consultas SQL usando psql? 2011-06-04 02:22:54 +0800 CST
  • Martin Hope
    Jonas Como inserir valores em uma tabela de uma consulta de seleção no PostgreSQL? 2011-05-28 00:33:05 +0800 CST
  • Martin Hope
    Jonas Como faço para listar todos os bancos de dados e tabelas usando o psql? 2011-02-18 00:45:49 +0800 CST

Hot tag

sql-server mysql postgresql sql-server-2014 sql-server-2016 oracle sql-server-2008 database-design query-performance sql-server-2017

Explore

  • Início
  • Perguntas
    • Recentes
    • Highest score
  • tag
  • help

Footer

AskOverflow.Dev

About Us

  • About Us
  • Contact Us

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve