簡體   English   中英

使用SQL查找給定時間范圍內的事件

[英]Finding events within a given timeframe with SQL

目前,我的大腦必須完全處於糊狀,因為我一直堅持下去。 我有一張桌子,上面標有某人服用某種葯物的日期,並且附有他們服葯的天數。 可以為一個人開出n種葯物的處方,因此以下查詢的CTE是查找最大的時間范圍(葯物的填充日期+天數。)然后,我想查找至少有7種不同葯物的患者葯物在同一時間。 我在給定時間范圍內找到人們正在使用的毒品時遇到了麻煩。 這需要限制在一個人一次至少服用seven葯物的時間范圍內。 一切正常,直到最后一部分。

來自CTE的樣本數據(fillDate + longestscript =結尾日期)

在此處輸入圖片說明

並發腳本由查詢中的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

您可以在第二個查詢中看到每個患者出現很多次,而fillDate和endingDate之間的時間間隔不同。 如何編寫查詢以使第二個屏幕帽的第一行重復使用這九種葯物? SQL Server 08 r2是我的dbms。

您是否有機會使用SQL Server 2012? 解決的辦法是在數據庫簡單得多 ,因為微軟延長了窗口功能,包括部分款項。

這個想法是要計算每個可能日期(無論是填充日期還是結束日期)的累積填充和結束次數。 然后區別是累積腳本的數量。 下面提供了每個日期的信息:

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

結果集中的每一行都有一個“下一個”,它定義了條件保持的時間段。 隨着患者從7到8到9到8到9到7並發處方,您可能會在一段時間內獲得多個記錄。

如果您有很多數據,這將是一個效率很低的查詢,因為它正在執行相當昂貴的聯接操作。 正如我所說,這在SQL Server 2012中將非常有效。

我不太確定您的架構,所以我稍作猜測,但是我注意到的第一件事是,在CTE x ,您選擇的是MAX(DaysSup)但也按dayssup分組,從而使max成為多余的。

但是,我真的不認為這與您的問題有關。 我個人將采用其他方法來解決此問題。 我假設您有一張桌子沿線:

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;

我已經介紹了第一部分,第二部分僅將結果限制為使用7種或更多葯物的所有日期。 第三個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;

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM