用于汇总和分组的T-SQL逻辑

9rbhqvlz  于 2022-10-22  发布在  其他
关注(0)|答案(2)|浏览(162)

根据下面的逻辑,我有一个问题要折叠或汇总数据。我如何实现它?
允许将事件浓缩为单个连续护理事件的逻辑是在同一天出院代码为22,随后是入院代码为4。


continuous care implementation update
EPN——是一个业务密钥。
epiodecontinuouscarekey是一个可以是行号函数的人工密钥。
下面是表格结构。

drop table #source
            CREATE TABLE #source(patidid varchar(20),epn int,preadmitdate datetime,adminttime varchar(10),
            admitcode varchar(10),datedischarge datetime,disctime varchar(10),disccode varchar(10))
            INSERT INTO #source VALUES
             (1849,1,'4/23/2020','7:29',1,'7/31/2020','9:03',22)
            ,(1849,2,'7/31/2020','11:00',4,'7/31/2020','12:09',22)
            ,(1849,3,'7/31/2020','13:10',4,'8/24/2020','10:36',10)
            ,(1849,4,'8/26/2020','12:25',2,null,null,null)
            ,(1850,1,'4/23/2020','7:33',1,'6/29/2020','7:30',22)
            ,(1850,2,'6/29/2020','9:35',4,'7/8/2020','10:51',7)
            ,(1850,3,'7/10/2020','11:51',3,'7/29/2020','9:12',7)
            ,(1850,4,'7/31/2020','11:00',2,'8/6/2020','10:24',22)
            ,(1850,5,'8/6/2020','12:26',4,null,null,null)
            ,(1851,1,'4/23/2020','7:35',1,'6/24/2020','13:45',22)
            ,(1851,2,'6/24/2020','15:06',4,'9/24/2020','15:00',2)
            ,(1851,3,'12/4/2020','8:59',0,null,null,null)
            ,(1852,1,'4/23/2020','7:37',1,'7/6/2020','11:15',20)
            ,(1852,2,'7/8/2020','10:56',0,'7/10/2020','11:46',2)
            ,(1852,3,'7/10/2020','11:47',2,'7/28/2020','13:16',22)
            ,(1852,4,'7/28/2020','15:17',4,'8/4/2020','11:37',22)
            ,(1852,5,'8/4/2020','13:40',4,'11/18/2020','15:43',2)
            ,(1852,6,'12/2/2020','15:23',2,null,null,null)
            ,(1853,1,'4/23/2020','7:40',1,'7/1/2020','8:30',22)
            ,(1853,2,'7/1/2020','14:57',4,'12/4/2020','12:55',7)
            ,(1854,1,'4/23/2020','7:44',1,'7/31/2020','13:07',20)
            ,(1854,2,'8/3/2020','16:30',0,'8/5/2020','9:32',2)
            ,(1854,3,'8/5/2020','10:34',2,'8/24/2020','8:15',22)
            ,(1854,4,'8/24/2020','10:33',4,'12/4/2020','7:30',22)
            ,(1854,5,'12/4/2020','9:13',4,null,null,null)
f0ofjuux

f0ofjuux1#

那张Excel表格图像几乎没有说明你的数据库设计,所以我发明了自己的版本,或多或少类似于你的图像。有了适当的数据库设计,解决方案的第一步就不需要了。。。
1.取消输入时间戳信息,使得接纳时间戳和排出时间戳成为一列。

  • 我在这个操作中使用了一个通用的表表达式Log1*

1.使用代码筛选出连续护理期的开始。这些是录取通知书,在我的数据库设计中用Code.IsAdmission = 1标记。
另外,使用lead()函数将下一个句点开始添加为另一列。

  • 这些都是Log2的所有操作*

1.添加行号作为连续护理键。
使用下一个期间开始日期,查找当前连续期间结束日期(cross apply)。
使用coalesce()函数将空的期间结束日期替换为当前日期。
使用datediff()函数计算差值作为连续护理期持续时间。

样本数据

create table Codes
(
  Code int,
  Description nvarchar(50),
  IsAdmission bit
);

insert into Codes (Code, Description, IsAdmission) values
( 1, 'First admission', 1),
( 2, 'Re-admission', 1),
( 4, 'Campus transfer IN', 0),
(10, 'Trial visit', 0),
(22, 'Campus transfer OUT', 0);

create table PatientLogs
(
  PatientId int,
  AdmitDateTime smalldatetime,
  AdmitCode int,
  DischargeDateTime smalldatetime,
  DischargeCode int
);

insert into PatientLogs (PatientId, AdmitDateTime, AdmitCode, DischargeDateTime, DischargeCode) values
(1849, '2020-04-23 07:29', 1, '2020-07-31 09:03', 22),
(1849, '2020-07-31 11:00', 4, '2020-07-31 12:09', 22),
(1849, '2020-07-31 13:10', 4, '2020-08-24 10:36', 10),
(1849, '2020-08-26 12:25', 2, null, null);

解决方案

with Log1 as
(
  select updt.PatientId,
         case updt.DateTimeType
           when 'AdmitDateTime' then updt.AdmitCode
           when 'DischargeDateTime' then updt.DischargeCode
         end as Code,
         updt.LogDateTime,
         updt.DateTimeType
  from PatientLogs pl
  unpivot (LogDateTime for DateTimeType in (AdmitDateTime, DischargeDateTime)) updt
),
Log2 as (
  select l.PatientId,
         l.Code,
         l.LogDateTime,
         lead(l.LogDateTime) over(partition by l.PatientId order by l.LogDateTime) as LogDateTimeNext
  from Log1 l
  join Codes c
    on c.Code = l.Code
  where c.IsAdmission = 1
)
select la.PatientId,
       row_number() over(partition by la.PatientId order by la.LogDateTime) as ContCareKey,
       la.LogDateTime as AdmitDateTime,
       coalesce(ld.LogDateTime, convert(smalldatetime, getdate())) as DischargeDateTime,
       datediff(day, la.LogDateTime, coalesce(ld.LogDateTime, convert(smalldatetime, getdate()))) as ContStay
from Log2 la -- log admission
outer apply ( select top 1 l1.LogDateTime
              from Log1 l1
              where l1.PatientId = la.PatientId
                and l1.LogDateTime < la.LogDateTimeNext
              order by l1.LogDateTime desc ) ld -- log discharge
order by la.PatientId,
         la.LogDateTime;

结果

PatientId  ContCareKey  AdmitDateTime     DischargeDateTime  ContStay
---------  -----------  ----------------  -----------------  --------
1849       1            2020-04-23 07:29  2020-08-24 10:36   123
1849       2            2020-08-26 12:25  2021-02-03 12:49   161

Fiddle查看实际情况和中间结果。

tf7tbtn2

tf7tbtn22#

这是一个包含主键和外键关系的T-SQL解决方案。
为了更逼真一点,我添加了一个简单的“患者”表。
我把你所有的“代码”放在一个表中,这样可以更容易地管理代码。
我不明白你的“持续护理”概念的目的,所以我只是在入院表中添加了一个“是第一个”的二进制列。您还可以考虑添加一些关于患者正在接受治疗的医疗状况的信息。


小时

CREATE SCHEMA Codes
GO

GO

CREATE TABLE dbo.Code
(
    codeNr int NOT NULL,
    description nvarchar(50),
    CONSTRAINT Code_PK PRIMARY KEY(codeNr)
)
GO

CREATE TABLE dbo.Patient
(
    patientNr int NOT NULL,
    birthDate date NOT NULL,
    firstName nvarchar(max) NOT NULL,
    lastName nvarchar(max) NOT NULL,
    CONSTRAINT Patient_PK PRIMARY KEY(patientNr)
)
GO

CREATE TABLE dbo.Admission
(
    admitDateTime time NOT NULL,
    patientNr int NOT NULL,
    admitCode int,
    isFirst bit,
    CONSTRAINT Admission_PK PRIMARY KEY(patientNr, admitDateTime)
)
GO

CREATE TABLE dbo.Discharge
(
    dischargeDateTime time NOT NULL,
    patientNr int NOT NULL,
    dischargeCode int NOT NULL,
    CONSTRAINT Discharge_PK PRIMARY KEY(patientNr, dischargeDateTime)
)
GO

ALTER TABLE dbo.Admission ADD CONSTRAINT Admission_FK1 FOREIGN KEY (patientNr) REFERENCES dbo.Patient (patientNr) ON DELETE NO ACTION ON UPDATE NO ACTION
GO

ALTER TABLE dbo.Admission ADD CONSTRAINT Admission_FK2 FOREIGN KEY (admitCode) REFERENCES dbo.Code (codeNr) ON DELETE NO ACTION ON UPDATE NO ACTION
GO

ALTER TABLE dbo.Discharge ADD CONSTRAINT Discharge_FK1 FOREIGN KEY (patientNr) REFERENCES dbo.Patient (patientNr) ON DELETE NO ACTION ON UPDATE NO ACTION
GO

ALTER TABLE dbo.Discharge ADD CONSTRAINT Discharge_FK2 FOREIGN KEY (dischargeCode) REFERENCES dbo.Code (codeNr) ON DELETE NO ACTION ON UPDATE NO ACTION
GO

GO

相关问题