0

私はこれに固執しているので、私の脳は現時点で完全にドロドロになっているに違いありません。私は誰かが薬を与えられた日付の表を持っています、そしてこれは彼らが薬を服用することになっている日数と一緒に来ます。人は薬の数を処方できるnので、次のクエリのCTEは、最大の時間枠(薬の充填日+供給日数)を見つけることです。次に、少なくとも7つの異なる薬を服用している人を見つけたいと思います。同時に。私は人々が与えられた時間枠で服用している薬を見つけるのに苦労しています。これは、人が少なくともseven一度に薬を服用していた期間に制限する必要があります。その最後の部分まで、すべてが正常に機能します。

CTEからのサンプルデータ(fillDate + longestscript =endingDate)

ここに画像の説明を入力してください

並行スクリプトはcount(distinct rx.drugname)、クエリで決定されます

ここに画像の説明を入力してください

  ;with cte 
as
(
      select rx.patid
        ,rx.fillDate
        ,MAX(rx.dayssup) as longestScript
        ,DATEADD(day,cast(rx.dayssup as int),rx.filldate) as endingDate
        from rx
        group by rx.patid, rx.fillDate,rx.daysSup
 ),
 startends as (
         select patid, FillDate as thedate, 1 as isstart 0 as isend
         from CTE union all
         select patid, EndingDate as thedate, 0 as isstart, 1 as isend
         from CTE
     ),
     cums as (
         select se.*,
                (select min(thedate) from startends se2 where se2.filledate > se.filldate) as nextdate,
                (select SUM(isstart) from startends se2 where se2.filldate <= se.filldate) as cumstarts,
                (select SUM(isend) from startends se2 where se2.filldate <= se.filldate) as cumends
         from startends se
     )
select *
from cums
where sumstarts - cumends >= 7

2番目のクエリでは、fillDateとendingDateの間の期間が異なる各患者が何度も表示されていることがわかります。2番目のスクリーンキャップの最初の行で9つの薬を繰り返すクエリを作成するにはどうすればよいですか?SQL Server08r2は私のdbmsです。

4

2 に答える 2

2

万が一、SQL Server 2012を使用していますか?Microsoftがウィンドウ関数を拡張して部分和を含めるようにしたため、このデータベースではソリューションがはるかに簡単になりました。

アイデアは、可能な各日付での累積フィルと終了の数を計算することです-フィル日か終了日かは関係ありません。次に、違いは累積スクリプトの数です。以下に、各日付の情報を示します。

with cte as (<your query>),
     startends as (
         select patid, FillDate as thedate, 1 as isstart 0 as isend
         from CTE union all
         select patid, EndingDate as thedate, 0 as isstart, 1 as isend
         from CTE
     ),
     cums as (
         select se.*,
                (select min(thedate) from startends se2 where se2.filledate > se.filldate) as nextdate,
                (select SUM(isstart) from startends se2 where se2.filldate <= se.filldate) as cumstarts,
                (select SUM(isend) from startends se2 where se2.filldate <= se.filldate) as cumends
         from startends se
     )
select *
from cums
where cumstarts - cumends >= 7

結果セットの各行には、条件が保持される期間を定義する「nextdate」があります。患者は7から8から9から8から9から7の同時処方になるため、おそらく1つの期間に複数のレコードが作成されることになります。

大量のデータがある場合、これはかなりコストのかかる結合操作を実行するため、かなり非効率的なクエリになります。ただし、私が言っているように、これはSQLServer2012では非常に効率的です。

于 2012-11-12T19:55:45.990 に答える
1

スキーマがよくわからないので少し推測しますが、最初に気付くのは、CTExで選択しているMAX(DaysSup)だけでなく、グループ化しdayssupて最大値を冗長にしていることです。

しかし、これがあなたの問題に関連しているとは思いません。私は個人的にこれを解決するために別のアプローチを取ります。私はあなたが次の線に沿ってテーブルを持っていると仮定しています:

CREATE TABLE rx
(       PatID           INT,
        FillDate        DATE,
        Dayssup         INT,
        DrugName        VARCHAR(50)
)

したがって、次の線に沿って何かを行うことができます。

SELECT  rx.PatID,
        rx.FillDate,
        rx.DrugName,
        [DateTaken] = DATEADD(DAY, v.Number, FillDate)
FROM    RX
        INNER JOIN master..spt_values v
            ON v.Number BETWEEN 0 AND rx.DaysSup
            AND v.Type = 'P'

これにより、範囲ではなく、各患者が薬を服用したすべての日付のリストが表示されるため、次のようなものを使用できます。

WITH x AS
(   SELECT  rx.PatID,
            rx.FillDate,
            rx.DrugName,
            [DateTaken] = DATEADD(DAY, v.Number, FillDate) 
    FROM    rx
            INNER JOIN master..spt_values v
                ON v.Number BETWEEN 0 AND rx.DaysSup
                AND v.Type = 'P'
), y AS
(   SELECT  x.PatID,
            x.DateTaken,
            DrugsTaken = COUNT(DISTINCT x.DrugName)
    FROM    x
    GROUP BY x.PatID, x.DateTaken
    HAVING COUNT(DISTINCT x.DrugName) >= 7
), z AS
(   SELECT  *,
            GroupID = DATEDIFF(DAY, - ROW_NUMBER() OVER(PARTITION BY PatID ORDER BY DateTaken DESC), DateTaken)
    FROM    y
)
SELECT  z.PatID, 
        [MostConccurent] = MAX(z.DrugsTaken),
        [DateStarted] = MIN(z.DateTaken),
        [DateEnded] = MAX(z.DateTaken)
FROM    z
GROUP BY z.PatID, z.GroupID;

私がカバーした最初の部分、2番目の部分は単に結果を7つ以上の薬を含むすべての日付に制限します。3番目のCTEは各患者を連続した日付でグループ化し、最後のCTEはそれらの各日付の最小値と最大値を取得します。

これらの日付のそれぞれに服用した薬のリストが必要な場合は、cteに戻ることができますx

SELECT  z.PatID, 
        x.DrugName,
        [MostConccurent] = MAX(z.DrugsTaken),
        [DateStarted] = MIN(z.DateTaken),
        [DateEnded] = MAX(z.DateTaken)
FROM    z
        INNER JOIN x
            ON x.PatID = z.PatID
            AND x.DateTaken = z.DateTaken
GROUP BY z.PatID, z.GroupID, x.DrugName;
于 2012-11-12T20:19:11.190 に答える