3

数日前、再帰クエリのヘルプに関してSOについて質問しました。

その質問の問題は、「人の予定の履歴を取得する方法」でした。

今、私はそれに似た問題を抱えていますが、少し異なる質問に答えるはずです:

How to get an Appointment history?

たとえば、ID = 5の予定が一度延期され、それが別の予定の延期だった場合、次の結果を得るにはどうすればよいですか?

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

助けてくれてありがとう

更新

これらのスクリプトは、トライアル用のテーブルを作成するのに役立ちます

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]
4

3 に答える 3

3

私は彼の答えを完全に乗っ取ったくなかったので、:

ブラッドの答えを使用する

完全な履歴を取得するためのクエリは次のとおりです。

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
于 2010-10-25T16:47:56.007 に答える
3

論理:

  1. 問題の予定を取得する
  2. 親アプリケーションへの参加を繰り返します
  3. すべての結果を選択

クエリ:

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)
于 2010-10-25T16:52:56.633 に答える
2

OPからの質問への回答:

効果的なデート

有効な日付とはDateTime、レコードがいつ「有効」になるかを制御する列をテーブルに追加することです。次に、列がPKテーブルのに追加され、各エントリが特定の時点(発効日)で「有効」だったものの記録になります。効果的なデートでは、あなたは決してDELETEまたは、あなたが常に時間の経過とともにオブジェクトの完全な履歴を持っていることを意味するUPDATEだけです。INSERT

最も効果的なレコードを見つけるには、将来ではない最大の効果を持つ行を選択します

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

これは、レコードより前の日付を設定できることを意味します。たとえば、今日、昇給が承認されましたが、2週間は有効になりません。

したがって、予定の履歴を見つけるには、次のようにします。

SELECT *
FROM   Appointments
WHERE  AppointmentId = @appointmentId
ORDER BY EffectiveDate
于 2010-10-25T17:28:06.960 に答える