SQL query - Join that returns the first two records of joining table

后端 未结 8 1731
陌清茗
陌清茗 2021-02-02 03:50

I have two tables:

Patient

  • pkPatientId
  • FirstName
  • Surname

PatientStatus

  • pk
8条回答
  •  迷失自我
    2021-02-02 04:13

    EDIT: Both of the following solutions require that PatientStatus.StartDate is unique within each patient.

    The traditional way (SQL Server 2000 compatible):

    SELECT 
      p.pkPatientId,
      p.FirstName,
      p.Surname,
      ps.StatusCode,
      ps.StartDate,
      ps.EndDate
    FROM 
      Patient p 
      INNER JOIN PatientStatus ps ON 
        p.pkPatientId = ps.fkPatientId
        AND ps.StartDate IN (
          SELECT TOP 2 StartDate 
          FROM     PatientStatus 
          WHERE    fkPatientId = ps.fkPatientId
          ORDER BY StartDate  /* DESC (to switch between first/last records) */
        )
    WHERE 
      EXISTS (
        SELECT   1 
        FROM     PatientStatus
        WHERE    fkPatientId = p.pkPatientId
        GROUP BY fkPatientId
        HAVING   COUNT(*) >= 2
      )
    ORDER BY 
      ps.fkPatientId, 
      ps.StartDate
    

    A more interesting alternative (you'd have to try how well it performs in comparison):

    SELECT 
      p.pkPatientId,
      p.FirstName,
      p.Surname,
      ps.StatusCode,
      ps.StartDate,
      ps.EndDate
    FROM 
      Patient p 
      INNER JOIN PatientStatus ps ON p.pkPatientId = ps.fkPatientId
    WHERE
      /* the "2" is the maximum number of rows returned */
      2 > (
        SELECT 
          COUNT(*)
        FROM 
          Patient p_i 
          INNER JOIN PatientStatus ps_i ON p_i.pkPatientId = ps_i.fkPatientId
        WHERE
          ps_i.fkPatientId = ps.fkPatientId
          AND ps_i.StartDate < ps.StartDate
          /* switch between "<" and ">" to get the first/last rows */
      )
      AND EXISTS (
        SELECT   1 
        FROM     PatientStatus
        WHERE    fkPatientId = p.pkPatientId
        GROUP BY fkPatientId
        HAVING   COUNT(*) >= 2
      )
    ORDER BY 
      ps.fkPatientId, 
      ps.StartDate
    

    Side note: For MySQL the latter query might be the only alternative - until LIMIT is supported in sub-queries.

    EDIT: I added a condition that excludes patients with only one PatientStatus record. (Thanks for the tip, Ryan!)

提交回复
热议问题