同様の問題を熟考し、それが完全な解決策を提供しなかったことを発見した後、私はついに解決できない問題の核心にたどり着きました。一定量の薬を処方できる日数を探しています。処方箋は開始および終了するため、人がX個の薬を服用している間隔が複数ある可能性があります。次のSQLスクリプトは、すぐに投稿するクエリの結果セットを生成します。また、SQLServer2012を持っていません。
create table test
(pat_id int, cal_date date, grp_nbr int, drug_qty int,[ranking] int)
go
insert into test(pat_id,cal_date, grp_nbr,drug_qty,[ranking])
values
(1, '1/8/2007',7,2, 1),
(1, '1/9/2007',7,2, 1),
(1, '1/10/2007',7, 2,1),
(1, '1/11/2007',7, 2,1),
(1, '1/12/2007',7, 2,1),
(1, '1/13/2007',7, 2,1),
(1, '1/14/2007',7, 2,1),
(1, '1/15/2007',7, 2,1),
(1, '6/1/2007',7,2, 1),
(1, '6/2/2007',7,2, 1),
(1, '6/3/2007',7,2, 1)
ここで、この人が一度に2つの薬を服用していた2つの連続していない間隔があることに注意してください。省略された日には、drug_qtyは2つ以上でした。この例の最後の列は、問題の解決に役立てるためにグループ化できる別のフィールドを追加しようとしたものです(機能しませんでした)。
テーブルを作成するためのクエリ:
CREATE TABLE [dbo].[rx](
[pat_id] [int] NOT NULL,
[fill_Date] [date] NOT NULL,
[script_End_Date] AS (dateadd(day,[dayssup],[filldate])),
[drug_Name] [varchar](50) NULL,
[days_Sup] [int] NOT NULL,
[quantity] [float] NOT NULL,
[drug_Class] [char](3) NOT NULL,
CHECK(fill_Date <=script_End_Date
PRIMARY KEY CLUSTERED
(
[clmid] ASC
)
CREATE TABLE [dbo].[Calendar](
[cal_date] [date] PRIMARY KEY,
[Year] AS YEAR(cal_date) PERSISTED,
[Month] AS MONTH(cal_date) PERSISTED,
[Day] AS DAY(cal_date) PERSISTED,
[julian_seq] AS 1+DATEDIFF(DD, CONVERT(DATE, CONVERT(varchar,YEAR(cal_date))+'0101'),cal_date),
id int identity);
結果セットを生成するために使用しているクエリ:
;WITH x
AS (SELECT rx.pat_id,
c.cal_date,
Count(DISTINCT rx.drug_name) AS distinctDrugs
FROM rx,
calendar AS c
WHERE c.cal_date BETWEEN rx.fill_date AND rx.script_end_date
AND rx.ofinterest = 1
GROUP BY rx.pat_id,
c.cal_date
--the query example I used having count(1) =2, but to illustrate the non-contiguous intervals, in practice I need the below having statement
HAVING Count(*) > 1),
y
AS (SELECT x.pat_id,
x.cal_date
--c2.id is the row number in the calendar table.
,
c2.id - Row_number()
OVER(
partition BY x.pat_id
ORDER BY x.cal_date) AS grp_nbr,
distinctdrugs
FROM x,
calendar AS c2
WHERE c2.cal_date = x.cal_date)
SELECT *,
Rank()
OVER(
partition BY pat_id, grp_nbr
ORDER BY distinctdrugs) AS [ranking]
FROM y
WHERE y.pat_id = 1604012867
AND distinctdrugs = 2
カレンダーテーブルに「id」という名前の列を含めるべきではないという事実に加えて、このアプローチにひどく悪い点はありますか?クエリを取得して、distinctDrugs = xの個別の間隔を表示できますが、それはその整数に対してのみ機能し、1より大きいものには機能しません。これは、患者が2つの薬を服用している別々の間隔を見つけることができることを意味しますが、>1ではなくhaving句で=2を使用する場合に限ります。私は次のようなことはできません
SELECT pat_id,
Min(cal_date),
Max(cal_date),
distinctdrugs
FROM y
GROUP BY pat_id,
grp_nbr
これは、連続していない日付の2番目のグループを取得するためです。誰かがこの問題のエレガントな解決策を知っていますか?