Domanda

Alcuni giorni fa ho posto una domanda su SO riguardo aiuto su una query ricorsiva.

Il problema di quella domanda era "Come ottenere la cronologia degli appuntamenti di una persona".

Ora sto riscontrando un problema simile a quello ma dovrebbe rispondere a una domanda leggermente diversa:

How to get an Appointment history?

Ad esempio se l'Appuntamento con ID=5 è stato posticipato una volta e si trattava del rinvio di un altro appuntamento come ottengo il seguente risultato?

AppointmentID         PrevAppointmentID
-----------------    ----------------------
1                     NULL
5                     1
12                    5

Grazie dell'aiuto

Aggiornamento:

Questi script ti aiuteranno a creare la tabella per le tue prove

CREATE TABLE [dbo].[Appointments](
    [AppointmentID] [int] IDENTITY(1,1) NOT NULL,
    [IssueID] [int] NOT NULL,
    [Location] [varchar](255) NOT NULL,
    [Description] [varchar](255) NOT NULL,
    [AppointmentDate] [datetime] NOT NULL,
    [AppointmentHour] [datetime] NOT NULL,
    [Done] [bit] NOT NULL,
    [PrevAppointmentID] [int] NULL,
 CONSTRAINT [PK_Appointments] PRIMARY KEY CLUSTERED 
(
    [AppointmentID] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]
È stato utile?

Soluzione

Non ho voglia di dirottare completamente la sua risposta, così:

Utilizzo di risposta di Brad

Questa è la query per ottenere la storia completa:

WITH    cte
          AS ( SELECT   AppointmentId ,
                        PrevAppointmentId
               FROM     Appointments
               WHERE    AppointmentId = @AppointmentId
               UNION ALL
               SELECT   prev.AppointmentId ,
                        prev.PrevAppointmentId
               FROM     Appointments prev
                        INNER JOIN cte curr ON prev.AppointmentId = curr.PrevAppointmentId
             ),
        cte1
          AS ( SELECT   AppointmentId ,
                        PrevAppointmentId
               FROM     Appointments
               WHERE    AppointmentId = @AppointmentId
               UNION ALL
               SELECT   prev.AppointmentId ,
                        prev.PrevAppointmentId
               FROM     Appointments prev
                        INNER JOIN cte1 curr ON prev.PrevAppointmentId = curr.AppointmentId
             )
    SELECT  *
    FROM    cte
    UNION
    SELECT  *
    FROM    cte1

Altri suggerimenti

Logic:

  1. Ottenere la nomina in questione
  2. Ricorre unirsi alla applicazione padre
  3. Seleziona tutti i risultati

Domanda:

DECLARE @appointmentId INT
SET @appointmentId = 3

--
;
WITH  past
      AS ( SELECT   AppointmentId ,
                    PrevAppointmentId
           FROM     Appointments
           WHERE    AppointmentId = @AppointmentId
           UNION ALL
           SELECT   prev.AppointmentId ,
                    prev.PrevAppointmentId
           FROM     Appointments prev
                    INNER JOIN cte curr ON prev.AppointmentId = curr.PrevAppointmentId
         ),
    future
      AS ( SELECT   AppointmentId ,
                    PrevAppointmentId
           FROM     Appointments
           WHERE    AppointmentId = @AppointmentId
           UNION ALL
           SELECT   prev.AppointmentId ,
                    prev.PrevAppointmentId
           FROM     Appointments prev
                    INNER JOIN cte1 curr ON prev.PrevAppointmentId = curr.AppointmentId
         )
SELECT  *
FROM    past OPTION(MAXRECURSION 500)
UNION
SELECT  *
FROM    future OPTION(MAXRECURSION 500)

In risposta ad una domanda dell'OP:

Incontri efficaci

La datazione effettiva è quando aggiungi a DateTime colonna alla tabella che controlla quando il record diventa "effettivo".La colonna viene quindi aggiunta al file PK della tabella che rende ciascuna voce una registrazione di ciò che era "in vigore" in un dato momento (la data di entrata in vigore).Con gli appuntamenti efficaci, mai DELETE O UPDATE, soltanto INSERT il che significa che hai sempre un completare storia dell'oggetto nel tempo.

Per trovare il record più efficace, seleziona la riga con l'efficacia massima che non sia futura

SELECT *
FROM   Appointments a1
WHERE  EffectiveDate = (SELECT MAX(EffectiveDate)
                        FROM   Appointments a2
                        WHERE  a1.AppointmentId = a2.AppointmentId
                               AND a2.EffectiveDate <= ISNULL(@asOfDate, GETDATE()
                       )

Ciò significa che puoi anche tu pre-data record.Ad esempio, oggi ti viene approvato un aumento di stipendio, ma non entrerà in vigore prima di 2 settimane.

Quindi, per trovare la cronologia di un appuntamento, basterebbe semplicemente:

SELECT *
FROM   Appointments
WHERE  AppointmentId = @appointmentId
ORDER BY EffectiveDate
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top