私はSQL Server 2008を使用していますが、下のクエリの速度を上げようとしています。照会は、再入日に基づいて患者にポイントを割り当てる。SQL:CTEクエリの速度
例:患者は、1/2,1/5,1/7,1/8,1/9,2/4で見られます。私はお互いの3日以内に最初に訪問をグループ化したいです。 1/2-5がグループ化され、1/7-9がグループ化されます。 1/5の実際の訪問日が1/2であるため、1/5は1/7とグループ化されません。 1/7は1/2からの再送信であるため3点を受け取る。 1/7からの再送信であるため、2/4は3点も受信します。日付がグループ化されると、最初の日付が実際の訪問日となります。
ほとんどの記事は、データセットを制限したり、インデックスを追加して速度を上げることを推奨しています。私は約15,000に行の量を制限し、インデックスを追加しました。 45回のテスト訪問日/ 3人のテスト患者でクエリを実行すると、クエリの実行には1.5分かかります。私の実際のデータセットでは、8時間以上かかります。 1時間に<を実行するには、このクエリを取得するにはどうすればよいですか?私の質問を書く良い方法はありますか?私のインデックスは正しいか?どんな助けでも大歓迎です。
クエリの下に期待される結果の例。
;CREATE TABLE RiskReadmits(MRN INT, VisitDate DATE, Category VARCHAR(15))
;CREATE CLUSTERED INDEX Risk_Readmits_Index ON RiskReadmits(VisitDate)
;INSERT RiskReadmits(MRN,VisitDate,CATEGORY)
VALUES
(1, '1/2/2016','Inpatient'),
(1, '1/5/2016','Inpatient'),
(1, '1/7/2016','Inpatient'),
(1, '1/8/2016','Inpatient'),
(1, '1/9/2016','Inpatient'),
(1, '2/4/2016','Inpatient'),
(1, '6/2/2016','Inpatient'),
(1, '6/3/2016','Inpatient'),
(1, '6/5/2016','Inpatient'),
(1, '6/6/2016','Inpatient'),
(1, '6/8/2016','Inpatient'),
(1, '7/1/2016','Inpatient'),
(1, '8/1/2016','Inpatient'),
(1, '8/4/2016','Inpatient'),
(1, '8/15/2016','Inpatient'),
(1, '8/18/2016','Inpatient'),
(1, '8/28/2016','Inpatient'),
(1, '10/12/2016','Inpatient'),
(1, '10/15/2016','Inpatient'),
(1, '11/17/2016','Inpatient'),
(1, '12/20/2016','Inpatient')
;WITH a AS (
SELECT
z1.VisitDate
, z1.MRN
, (SELECT MIN(VisitDate) FROM RiskReadmits WHERE VisitDate > DATEADD(day, 3, z1.VisitDate)) AS NextDay
FROM
RiskReadmits z1
WHERE
CATEGORY = 'Inpatient'
), a1 AS (
SELECT
MRN
, MIN(VisitDate) AS VisitDate
, MIN(NextDay) AS NextDay
FROM
a
GROUP BY
MRN
), b AS (
SELECT
VisitDate
, MRN
, NextDay
, 1 AS OrderRow
FROM
a1
UNION ALL
SELECT
a.VisitDate
, a.MRN
, a.NextDay
, b.OrderRow +1 AS OrderRow
FROM
a
JOIN b
ON a.VisitDate = b.NextDay
), c AS (
SELECT
MRN,
VisitDate
, (SELECT MAX(VisitDate) FROM b WHERE b1.VisitDate > VisitDate AND b.MRN = b1.MRN) AS PreviousVisitDate
FROM
b b1
)
SELECT distinct
c1.MRN,
c1.VisitDate
, CASE
WHEN DATEDIFF(day,c1.PreviousVisitDate,c1.VisitDate) < 30 THEN PreviousVisitDate
ELSE NULL
END AS ReAdmissionFrom
, CASE
WHEN DATEDIFF(day,c1.PreviousVisitDate,c1.VisitDate) < 30 THEN 3
ELSE 0
END AS Points
FROM
c c1
ORDER BY c1.MRN
期待される結果:
MRN VisitDate ReAdmissionFrom Points
1 2016-01-02 NULL 0
1 2016-01-07 2016-01-02 3
1 2016-02-04 2016-01-07 3
1 2016-06-02 NULL 0
1 2016-06-06 2016-06-02 3
1 2016-07-01 2016-06-06 3
1 2016-08-01 NULL 0
1 2016-08-15 2016-08-01 3
1 2016-08-28 2016-08-15 3
1 2016-10-12 NULL 0
1 2016-11-17 NULL 0
1 2016-12-20 NULL 0
あなたはあなたに何を記述する必要があります(
が VisitDate 、MRN 、NextDay 、1 OrderRow AS A1 FROM SELECT)ASサンプルデータと望ましい結果を含めて、しようとしています。 –
また、codereview.stackexchange.comのサイト – scsimon
にこれを投稿することをお勧めします。 – JBritton