连续行之间的日期差异 - 复杂

2024-01-10

我之前发过一篇question https://stackoverflow.com/questions/9994862/date-difference-between-consecutive-rows已得到答复,但我也需要对此进行查询。 我有一个包含这样数据的表结构(日期格式为日/月/年).

ID    Account Number    Unit    Admit_Date    Disch_Date
1     1001              w32     01/04/2012    
2     1002              w32     01/04/2012    01/04/2012
3     1001              ccu     03/04/2012
4     1001              w33     05/04/2012
5     1003              cicu    04/04/2012
6     1001              ccu     07/04/2012
7     1001              ccu     07/04/2012    10/04/2012
8     1003              w33     05/04/2012
9     1003              w33     05/04/2012    08/04/2012

基本上,该表涉及患者入住特定病房并在病房之间转移,然后最终在同一天或几天后出院。 查询的预期结果将是:

Account_Number                                 No. Of Days
1001              01/04/2012    03/04/2012      2
1001              03/04/2012    05/04/2012      2
1001              05/03/2012    07/04/2012      2
1001              07/04/2012    10/04/2012      3
1002              01/04/2012    01/04/2012      0
1003              04/04/2012    05/04/2012      1
1003              05/04/2012    08/04/2012      3

出院日期字段仅在患者出院时填写,因此我想计算患者每次移动日期之间的日期差,包括入院日期和出院日期。

我使用 MS Access 2003。

我希望有人能够帮助我解决这个问题。


过滤掉不相关的数据

对于任何复杂的查询,艺术的一部分是逐步构建查询,并进行测试。

我假设表名称是 PatientMovements 并且:

给定行对,例如 ID = {6,7} 和 ID = {8,9},it is正确的说法是,当还存在同一患者、单位和入院日期但出院日期非空的记录时,忽略出院日期为空的患者(帐号)、单位和入院日期所在的行。

因此,第一步是生成我们需要处理的行,从数据库中记录的表中过滤掉不相关的数据。这是两组数据的 UNION:

  1. 具有非空放电日期的那些行。
  2. 这些行的出院日期为空,但没有相同帐户、单位和入院日期的行。

显然,UNION 的第一部分是:

SELECT * FROM PatientMovements WHERE DischargeDate IS NOT NULL

不太明显的是,UNION 的第二部分是:

SELECT *
  FROM PatientMovements AS p1
 WHERE DischargeDate IS NULL
   AND NOT EXISTS
       (SELECT *
          FROM PatientMovements AS P2
         WHERE P1.Account   = P2.Account
           AND P1.Unit      = P2.Unit
           AND P1.AdmitDate = P2.AdmitDate
           AND P2.DischargeDate IS NOT NULL
       )

现在您可以将它们组合成一个结果集:

SELECT *
  FROM PatientMovements
 WHERE DischargeDate IS NOT NULL
UNION
SELECT *
  FROM PatientMovements AS p1
 WHERE DischargeDate IS NULL
   AND NOT EXISTS
       (SELECT *
          FROM PatientMovements AS P2
         WHERE P1.Account   = P2.Account
           AND P1.Unit      = P2.Unit
           AND P1.AdmitDate = P2.AdmitDate
           AND P2.DischargeDate IS NOT NULL
       )

您可以通过检查上面的查询是否返回 ID 为 1..5、7 和 9 的行来验证它。

Warning:未经测试的代码。此答案中的 SQL 均未接近 DBMS,因此未经测试。

应用以前学到的经验教训

然后你就可以应用从其他人那里学到的知识question https://stackoverflow.com/questions/9994862/date-difference-between-consecutive-rows唯一的复杂之处是您必须将该查询写入两次,这很痛苦(除非 MS Access 2003 支持“WITH”子句或公用表表达式)。


但是是否没有单个查询可以获得所需的输出?

当然,UNION 是单个查询。我想你可以这样写:

SELECT *
  FROM PatientMovements
 WHERE (DischargeDate IS NOT NULL)
    OR (DischargeDate IS     NULL
        AND NOT EXISTS
            (SELECT *
               FROM PatientMovements AS P2
              WHERE P1.Account   = P2.Account
                AND P1.Unit      = P2.Unit
                AND P1.AdmitDate = P2.AdmitDate
                AND P2.DischargeDate IS NOT NULL
            )
       )

我无法立即想到一种更紧凑的查询方式。


将 UNION 打造为“另一个答案”

另一个问题的接受答案有两种可能的解决方案(经评论修改并重新格式化):

SELECT T1.ID, T1.AccountNumber, T1.Date, 
       MIN(T2.Date) AS NextDate, 
       DATEDIFF("D", T1.Date, MIN(T2.Date)) AS DaysDiff
  FROM YourTable T1
  JOIN YourTable T2
    ON T1.AccountNumber = T2.AccountNumber AND T2.Date > T1.Date

Or:

SELECT ID, AccountNumber, Date, NextDate,
       DATEDIFF("D", Date, NextDate) AS DaysDiff
  FROM (SELECT ID, AccountNumber, Date,
               (SELECT MIN(Date) 
                  FROM YourTable T2
                 WHERE T2.AccountNumber = T1.AccountNumber
                   AND T2.Date > T1.Date
               ) AS NextDate
          FROM YourTable T1
        ) AS T

正如评论中指出的,问题中缺少表名会导致答案中出现不同的表名;我所说的 PatientMovements 在这个答案中被称为 YourTable。另一个区别是原始问题不包括数据中的 Unit 或 DischargeDate 列。但是,我给出的 UNION 查询提供了运行这些查询的相关数据,因此剩下要做的就是将 UNION 查询写入其他答案中以代替 YourTable。这导致:

SELECT T1.ID, T1.AccountNumber, T1.Date, 
       MIN(T2.Date) AS NextDate, 
       DATEDIFF("D", T1.Date, MIN(T2.Date)) AS DaysDiff
  FROM (SELECT *
          FROM PatientMovements
         WHERE (DischargeDate IS NOT NULL)
            OR (DischargeDate IS     NULL
                AND NOT EXISTS
                    (SELECT *
                       FROM PatientMovements AS P2
                      WHERE P1.Account   = P2.Account
                        AND P1.Unit      = P2.Unit
                        AND P1.AdmitDate = P2.AdmitDate
                        AND P2.DischargeDate IS NOT NULL
                    )
               )
       ) AS T1
  JOIN (SELECT *
          FROM PatientMovements
         WHERE (DischargeDate IS NOT NULL)
            OR (DischargeDate IS     NULL
                AND NOT EXISTS
                    (SELECT *
                       FROM PatientMovements AS P2
                      WHERE P1.Account   = P2.Account
                        AND P1.Unit      = P2.Unit
                        AND P1.AdmitDate = P2.AdmitDate
                        AND P2.DischargeDate IS NOT NULL
                    )
               )
       ) AS T2
    ON T1.AccountNumber = T2.Accountnumber AND T2.Date > T1.Date

Or:

SELECT ID, AccountNumber, Date, NextDate,
       DATEDIFF("D", Date, NextDate) AS DaysDiff
  FROM (SELECT ID, AccountNumber, Date,
               (SELECT MIN(Date) 
                  FROM (SELECT *
                          FROM PatientMovements
                         WHERE (DischargeDate IS NOT NULL)
                            OR (DischargeDate IS     NULL
                                AND NOT EXISTS
                                    (SELECT *
                                       FROM PatientMovements AS P2
                                      WHERE P1.Account   = P2.Account
                                        AND P1.Unit      = P2.Unit
                                        AND P1.AdmitDate = P2.AdmitDate
                                        AND P2.DischargeDate IS NOT NULL
                                    )
                               )
                       ) AS T2
                 WHERE T2.Accountnumber = T1.AccountNumber
                   AND T2.Date > T1.Date
               ) AS NextDate
          FROM (SELECT *
                  FROM PatientMovements
                 WHERE (DischargeDate IS NOT NULL)
                    OR (DischargeDate IS     NULL
                        AND NOT EXISTS
                            (SELECT *
                               FROM PatientMovements AS P2
                              WHERE P1.Account   = P2.Account
                                AND P1.Unit      = P2.Unit
                                AND P1.AdmitDate = P2.AdmitDate
                                AND P2.DischargeDate IS NOT NULL
                            )
                       )
               ) AS T1
        ) AS T

因此,只要您小心,并在片段中开发查询,然后将它们一致地组合起来,就可以驯服看起来最糟糕的查询。

通用表表达式

请注意,SQL 标准具有“通用表表达式”(CTE),也称为“WITH 子句”,这可以使事情变得更容易。

WITH YourTable AS
   (SELECT *
      FROM PatientMovements
     WHERE (DischargeDate IS NOT NULL)
        OR (DischargeDate IS     NULL
            AND NOT EXISTS
                (SELECT *
                   FROM PatientMovements AS P2
                  WHERE P1.Account   = P2.Account
                    AND P1.Unit      = P2.Unit
                    AND P1.AdmitDate = P2.AdmitDate
                    AND P2.DischargeDate IS NOT NULL
                )
           )
     )
SELECT T1.ID, T1.AccountNumber, T1.Date, 
       MIN(T2.Date) AS NextDate, 
       DATEDIFF("D", T1.Date, MIN(T2.Date)) AS DaysDiff
  FROM YourTable T1
  JOIN YourTable T2
    ON T1.AccountNumber = T2.AccountNumber AND T2.Date > T1.Date

Or:

WITH YourTable AS
   (SELECT *
      FROM PatientMovements
     WHERE (DischargeDate IS NOT NULL)
        OR (DischargeDate IS     NULL
            AND NOT EXISTS
                (SELECT *
                   FROM PatientMovements AS P2
                  WHERE P1.Account   = P2.Account
                    AND P1.Unit      = P2.Unit
                    AND P1.AdmitDate = P2.AdmitDate
                    AND P2.DischargeDate IS NOT NULL
                )
           )
     )
SELECT ID, AccountNumber, Date, NextDate,
       DATEDIFF("D", Date, NextDate) AS DaysDiff
  FROM (SELECT ID, AccountNumber, Date,
               (SELECT MIN(Date) 
                  FROM YourTable T2
                 WHERE T2.AccountNumber = T1.AccountNumber
                   AND T2.Date > T1.Date
               ) AS NextDate
          FROM YourTable T1
        ) AS T

使用 CTE 的主要优点之一是,优化器被明确告知表表达式在所有使用的地方都是相同的,而当它被多次写出时,它可能无法发现这种共性。另外,多次编写查询可能会导致两个“本应相同”的查询实际上由于编辑错误而略有不同; CTE 排除了这种可能性。当前情况下的另一个优势是,将 CTE 与其他问题的解决方案结合起来就像小孩子的游戏一样。

遗憾的是,MS Access 2003 不太可能支持 CTE。我分担你的痛苦;我使用的 DBMS 主要也没有。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

连续行之间的日期差异 - 复杂 的相关文章

  • 在 SELECT IN 中使用 Oracle 参数时出现问题

    我在将一串数字插入sql查询时遇到问题 SELECT FROM tablename a WHERE a flokkurid IN 3857 3858 3863 3285 ORDER BY sjodategund rodun or SELEC
  • MySQL - 从临时表插入

    这看起来非常简单 但我坚持使用简单的插入语句 见下文 begin work CREATE TEMPORARY TABLE IF NOT EXISTS insert table AS select r resource id fr file
  • 给定“java.sql.SQLIntegrityConstraintViolationException”是否可以确定错误的列

    鉴于我有一个类型为 java sql SQLIntegrityConstraintViolationException 的异常 是否可以以编程方式确定错误的列 或多列 我问这个问题是因为我想将错误映射回客户端的数据模型以指示错误的字段 例如
  • date_sub 对于 mysql 可以,对于 postgresql 可以

    此查询适用于 mySQL 不适用于 Postgresql select from where id and h gt date sub now INTERVAL 30 MINUTE 错误是 Query failed ERREUR erreu
  • PL/pgSQL SELECT 到数组中

    这是我的函数声明和主体的一部分 CREATE OR REPLACE FUNCTION access update RETURNS void AS DECLARE team ids bigint BEGIN SELECT INTO team
  • 将 .MDF SQL Server 数据库与 ASP.NET 结合使用与使用 SQL Server

    我目前正在 ASP NET MVC 中编写一个网站 我的数据库 其中还没有任何数据 只有正确的表 使用 SQL Server 2008 我已将其安装在我的开发计算机上 我使用服务器资源管理器从应用程序连接到数据库 然后使用 LINQ to
  • 不带 GROUP BY 的聚合查询

    这个查询似乎在我的旧机器上完美运行 但是 在我的 MySQL 5 7 14 和 PHP 5 6 25 的新机器上 它会抛出错误 致命错误 未捕获异常 PDOException 并带有消息 SQLSTATE 42000 语法错误或访问冲突 1
  • PostgreSQL 中“-”处或附近的语法错误

    我正在尝试运行查询来更新用户密码 alter user dell sys with password Pass 133 但因为 它给了我这样的错误 ERROR syntax error at or near LINE 1 alter use
  • Postgresql 一张表的多个计数

    我想从表中的两列中获得这些列中值的统一计数 例如 两列是 表 报告 type place one home two school three work four cafe five friends six mall one work one
  • T-SQL:用最新的非空值替换 NULL 的最佳方法?

    假设我有这张表 id value 1 5 2 4 3 1 4 NULL 5 NULL 6 14 7 NULL 8 0 9 3 10 NULL 我想编写一个查询来替换任何NULL值与表中最后一个不为空的值在那一栏里 我想要这个结果 id va
  • 如何使用 vb.net 将数据插入 Access 表?

    我想在 Access 数据库中插入一个新行 我正在考虑做类似的事情 oConnection new Connection connectionstring oTable oCennection table Orders oRow oTabl
  • 实现软删除的最佳方法是什么?

    目前在做一个项目 我们要对大部分用户 用户角色 实现软删除 我们决定添加一个is deleted 0 数据库中每个表的字段并将其设置为 1 如果特定用户角色点击特定记录上的删除按钮 现在为了将来的维护 每个SELECT查询需要确保它们不包含
  • JDBC插入实数数组

    我试图将一个真实的数组插入到 postgresql 数组中 该表的定义是 String sqlTable CREATE TABLE IF NOT EXISTS ccmBlock sampleId INTEGER block REAL 插入内
  • 快速查询最新记录的方法?

    我有一张这样的表 USER PLAN START DATE END DATE 1 A 20110101 NULL 1 B 20100101 20101231 2 A 20100101 20100505 在某种程度上 如果END DATE i
  • 在 SQL Server 上执行分页的最佳方式是什么?

    我有一个数据库超过200万记录 我需要执行分页以在我的 Web 应用程序上显示 该应用程序每页必须有 10 条记录DataGrid 我已经尝试使用ROW NUMBER 但是这种方式会选择所有 200 万条记录 然后只得到 10 条记录 我也
  • H2 用户定义的聚合函数 ListAgg 不能在第一个参数上使用 DISTINCT 或 TRIM()

    所以我有一个 DB2 生产数据库 我需要在其中使用可用的函数 ListAgg 我希望使用 H2 的单元测试能够正确测试此功能 不幸的是H2不直接支持ListAgg 但是 我可以创建一个用户定义的聚合函数 import java sql Co
  • 如何通过 SQL 表关联 SQL 中的实体

    我是数据库设计的初学者 我需要为项目创建数据库 我可以用面向对象的术语解释我想要做什么 值得庆幸的是 数据库专家会很友善地向我解释如何在数据库方面处理这个问题 我想创建一个与位置实体 州 城市 有关系的用户 ID 名称 实体 所以在编程语言
  • SQL Server 连接其他表中不存在的位置

    Service Asset AssetService Id Name Id Name AssetId ServiceId
  • 如何在 SQL Server 中连接

    我的数据库没有特定的列 因此我通过开关在查询中创建了一个列 我需要的是将此列与数据库中的另一列连接起来 select certificateDuration DurationType case when certificateDuratio
  • 如何部署“SQL Server Express + EF”应用程序

    这是我第一次部署使用 SQL Server Express 数据库的应用程序 我首先使用实体 框架模型来联系数据库 我使用 Install Shield 创建了一个安装向导来安装应用程序 这些是我在目标计算机中安装应用程序所执行的步骤 安装

随机推荐

  • 使用 fxml (scenebuilder)制作的进度条来使用方法中的值[重复]

    这个问题在这里已经有答案了 我希望进度条显示返回双值的方法的值 但它不起作用 但我认为这不是主要问题 即使我只使用特定的数字 它也不起作用 请帮助我 提前致谢 这是一个具体的问题 所以我搜索了 cery 很长时间没有结果 所以如果你知道更好
  • nAnt 删除超过 7 天的文件

    我想创建一个目标来清理特定文件夹中超过 7 天的日志文件 当我尝试在文件集中放入 日期 元素时出现错误 我该怎么办
  • 更新单个表的多行

    我需要更新超过 60k 行的表的每一行 目前我正在这样做 public void updateRank Map
  • 超类型-子类型数据库设计

    我有一个关于关系数据库中超类型子类型设计的问题 如果我有一个带有两个子类型表的超类型 我会将与两个子类型表的 PK 相关的超类型的 PK 作为 FK 假设我有这样的事情 Type 类型 ID PK 超级类型 身份验证 类型ID FK Sub
  • CMake 中的布尔变量取反?

    假设我在 CMake 中设置以下变量 set foo TRUE 现在 我想定义一个bar具有相反布尔值的变量foo 换句话说 在这种情况下 我想要bar to be FALSE 或等价物 例如false or 0 完成此操作的一种方法是 i
  • 一起部署 DotNetNuke 和单独的 ASP.NET 应用程序 - 可能的问题?

    我这样做是为了积极主动地尝试阻止由此可能产生的任何潜在问题 情况是 我们正在为客户开发一个 ASP NET 应用程序 该应用程序将处理客户的在线订购 该应用程序将使用与其当前 WinForms 应用程序使用的相同数据库 这里没有真正的问题
  • python中的用户指针

    我正在尝试显示使用 v4l 捕获的网络摄像头的预览 下面是代码的大概样子 from ctypes import from v4l2 import from Image import fromstring from Tkinter impor
  • 嵌套构造函数。为什么需要它?

    class Character Entity def init self x y hp Entity init self x y self hp hp self items Character是父类的子类Entity Entity类还有一个
  • SecurityException:无法为用户 0 找到提供者 null;在 Android 8.0 上的 ActiveAndroid 上

    我有一个使用 ActiveAndroid 的应用程序 它运行良好 然而 现在 当我尝试将模型保存到数据库时 我收到 SecurityException 堆栈是 Error saving model java lang SecurityExc
  • 按下 ESC 时关闭灯箱

    我试图在按下转义键时关闭灯箱 但弹出窗口没有关闭 document keypress function e if e keyCode 27 popupStatus 1 disablePopup 这是完整的代码 var popupStatus
  • HTML5 和 CSS - 媒体查询运算符问题

    我想知道是否有人可以用简单的术语解释下面示例中的每个媒体查询的含义 这是示例 media not screen and color media projection screen and color media only projectio
  • 录制红色状态栏上的自定义文本

    我的应用程序在 Info plist 中被标记为 VoiP 和 Audio 因此当后台发生任何录制时 红色状态栏会出现并显示文本 Recording 我想知道是否可以修改此文本 我到处搜索 但在文档中找不到与之关联的参数 Thanks 看起
  • UWP Windows 应用商店应用上的 TLS 客户端证书身份验证

    我正在尝试连接到使用 TLS 进行客户端证书身份验证的服务器 下面是一个代码片段 async Task TestClientCertAuth int iWinInetError 0 Uri theUri new Uri http xxx x
  • VS 2012 上的 LLVM 3.4 链接器错误

    我已经使用 Cmake 从源代码构建了 LLVM 3 4 我参考了使用 Microsoft Visual Studio 进行安装的 LLVM 系统入门文档 我现在想在我自己的项目中使用 LLVM 我已经使用以下命令在 VS 2012 中添加
  • 在 hadoop 中使用 Pig 中的正则表达式

    我有一个包含用户 tweetid tweet userid 的 CSV 文件 396124436476092416 Think about the life you livin but don t think so hard it hurt
  • Google Maps API 3 - 不支持缩放

    我正在尝试开发一个 HTML 页面 通过 Google 地图 API 显示 KML 文件 页面链接 http www slocleanair org air AQI III mapTest html http www slocleanair
  • 使用 Pandas 替换缺失值

    Country USA Age 52 Sal 12345 OnWork No Country UK Age 23 Sal 1142 OnWork Yes Country MAL Age 25 Sal 4456 OnWork No Count
  • JavaScript 正则表达式

    当我遇到这个问题时 我正在尝试为其他人做正则表达式 要求是正则表达式应该从一组字符串中返回结果 比方说 其中包含 apple 例如 考虑以下字符串 I have an apple You have two Apples I give you
  • 如何将 Papa.parse 结果放入数组中

    预警 我是 js 新手 我编写的以下代码取自从 Javascript 对象中的 CSV 检索解析后的数据 使用 Papa Parse https stackoverflow com questions 26266459 retrieve p
  • 连续行之间的日期差异 - 复杂

    我之前发过一篇question https stackoverflow com questions 9994862 date difference between consecutive rows已得到答复 但我也需要对此进行查询 我有一个