【问题标题】:Select every second record then determine earliest date选择每隔一条记录,然后确定最早的日期
【发布时间】:2020-12-12 12:55:06
【问题描述】:

我的表格如下所示

我必须选择每个 PatientID 的每一秒记录,这会给出以下结果(我的最后一个查询返回此结果)

然后我必须选择日期最早的记录,如下所示(这是我想要的最终结果)

到目前为止我所做的:我有一个 CTE,可以获取我需要的所有数据

WITH cte
AS 
(
    SELECT visit.PatientTreatmentVisitID, mat.PatientMatchID,pat.PatientID,visit.RegimenDate AS VisitDate, 
                        ROW_NUMBER() OVER(PARTITION BY mat.PatientMatchID, pat.PatientID ORDER BY visit.VisitDate ASC) AS RowNumber
    FROM tblPatient pat INNER JOIN tblPatientMatch mat ON mat.PatientID = pat.PatientID
    LEFT JOIN tblPatientTreatmentVisit visit ON visit.PatientID = pat.PatientID
)

然后我针对 CTE 编写查询,但到目前为止我只能返回每个患者 ID 的第二行

SELECT *
FROM 
(
    SELECT PatientTreatmentVisitID,PatientMatchID,PatientID, VisitDate,  RowNumber FROM cte    
) as X
WHERE RowNumber = 2 

如何只返回日期最早的记录?是否有我可以在某处包含的 MIN() 函数?

【问题讨论】:

  • 如果您指定了您正在使用的 RDBMS 和版本,这将有所帮助,例如SQL Server 2008(或其他)
  • 我使用的是 SQL Server 2016
  • 向我们扔这么多粗体并不会使问题更容易阅读。同样在未来,我们更喜欢将数据格式化为文本,而不是图像。

标签: sql sql-server sql-order-by greatest-n-per-group window-functions


【解决方案1】:

如果我正确地跟随你,你可以只订购现有的结果集并只保留第一行。

在标准 SQL 中,您可以使用 FETCH 子句来编写:

SELECT *
FROM (
    SELECT
        visit.PatientTreatmentVisitID, 
        mat.PatientMatchID,
        pat.PatientID,
        visit.RegimenDate AS VisitDate, 
        ROW_NUMBER() OVER(PARTITION BY mat.PatientMatchID, pat.PatientID ORDER BY visit.VisitDate ASC) AS rn
    FROM tblPatient pat 
    INNER JOIN tblPatientMatch mat ON mat.PatientID = pat.PatientID
    LEFT JOIN tblPatientTreatmentVisit visit ON visit.PatientID = pat.PatientID
) t
WHERE rn = 2
ORDER BY VisitDate
OFFSET 0 ROWS FETCH FIRST 1 ROW ONLY

Postgres、Oracle、SQL Server(可能还有其他数据库)支持这种语法。

【讨论】:

    【解决方案2】:

    如果您需要从所有选定日期(每个患者 ID 的每第二行)中获取最早的日期,那么您可以尝试 window function Min:

    SELECT * FROM
    (
    SELECT *, MIN(VisitDate) OVER (Order By VisitDate) MinDate
      FROM 
       (
        SELECT    PatientTreatmentVisitID,PatientMatchID,PatientID, VisitDate,  
        RowNumber FROM cte  
       ) as X
       WHERE RowNumber = 2 
    ) Y
    WHERE VisitDate=MinDate
    

    或者您可以使用 SELECT TOP 语句。 SELECT TOP clause 允许您限制查询结果集中返回的行数:

    SELECT TOP 1 PatientTreatmentVisitID,PatientMatchID,PatientID, VisitDate FROM  
       (
         SELECT *
         FROM 
         (
          SELECT PatientTreatmentVisitID,PatientMatchID,PatientID, VisitDate,  
          RowNumber FROM cte    
         ) as X
       WHERE RowNumber = 2 
      ) Y
      ORDER BY VisitDate
    

    【讨论】:

    • 格拉夫,你试试查询吗?
    【解决方案3】:

    为简单起见,在日期列上添加 order desc 并使用 TOP 仅获取第一行

    SELECT TOP 1 *
    FROM 
    (
        SELECT PatientTreatmentVisitID,PatientMatchID,PatientID, VisitDate,  RowNumber FROM cte    
    ) as X
    WHERE RowNumber = 2 
    order by VisitDate desc
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-01-30
      • 1970-01-01
      • 2020-08-22
      • 1970-01-01
      • 2013-03-05
      • 1970-01-01
      相关资源
      最近更新 更多