为一个季度中的每一天创建具有处方金额的日期表
Posted
技术标签:
【中文标题】为一个季度中的每一天创建具有处方金额的日期表【英文标题】:Create Date Table With Prescription Amount for Every Day in a Quarter 【发布时间】:2013-10-02 19:35:28 【问题描述】:我正在尝试开发一个查询来确定个人在一个季度内每天服用的药物量。在某些日子里,没有处方药,而对于其他日子,可能会有重叠,我需要一个总量(意思是,一天中每种药物的强度)。药物的数量、强度、日用品等可能会有所不同。以下是一些数据:
create table #MemberInfo
(ProgramName varchar(255),
DateFilled datetime,
DaySupply integer,
MemberID varchar(255),
Strength integer,
Tradename varchar(255));
insert into #MemberInfo
Values ('InsureCo', '20130612', 30, 'MEM001', 10, 'Sedative')
, ('InsureCo', '20130429', 30, 'MEM001', 20, 'Sedative')
, ('InsureCo', '20130401', 30, 'MEM001', 20, 'Sedative')
, ('InsureCo', '20130529', 30, 'MEM001', 30, 'Sedative')
我真的不知道最好的方法是将一个季度中某一天服用的药物量加起来。如果可以的话,我想避免使用游标。我正在考虑创建一个包含一个季度所有天数的临时表,然后以某种方式将这些日期加入到每天服用药物(即,DateFilled + 之后的每一天直到 DaySupply)。一旦我掌握了一个季度内每种药物的日期和数量,我就可以按天分组并获得每天的总和。我还需要能够获得超过四分之一的平均金额。
附加要求:
-
我有一个开始日期和天数。我想创建一行
每个成员每天都有处方(并执行
他们所有的处方都一样)。然后我会总结力量
每天的所有药物。如果有帮助,所有的药物
将是同一级别的,并且强度将是相等的
剂量,这意味着我可以总结它们。
对于报告,我需要能够计算 数量大于某个截止值(比如说 100)。这就是为什么我 尝试获取每天的金额。
Desired output
MemberID Date SumStrength
MEM001 2013-04-29 40
MEM001 2013-04-30 40
MEM001 2013-05-01 20
ETC FOR EVERY DAY FOR THIS MEMBER
MEM002 2013-04-01 60
MEM002 2013-04-02 40
ETC FOR EVERY DAY FOR THIS MEMBER
【问题讨论】:
这是一个很好的开始。现在所缺少的只是您希望从示例数据中获得的示例输出以及您自己实际检索该输出的努力,我们可以尝试帮助您找到答案。 我在原始问题中添加了一些简短的示例输出。提前致谢。这比我过去写的大多数查询要复杂一些。 我已将medical
标记删除为无关紧要。您的问题不是具体的医疗问题,因为它仅与金额和日期有关。
【参考方案1】:
我认为只是一个简单的组。
create table #MemberInfo
(ProgramName varchar(255),
DateFilled datetime,
DaySupply integer,
MemberID varchar(255),
Strength integer,
Tradename varchar(255));
insert into #MemberInfo
Values ('InsureCo', '20130612', 30, 'MEM001', 10, 'Sedative')
, ('InsureCo', '20130429', 30, 'MEM001', 20, 'Sedative')
, ('InsureCo', '20130429', 30, 'MEM002', 25, 'Sedative')
, ('InsureCo', '20130515', 30, 'MEM002', 25, 'Sedative')
, ('InsureCo', '20130401', 30, 'MEM001', 20, 'Sedative')
, ('InsureCo', '20130529', 30, 'MEM001', 30, 'Sedative')
, ('InsureCo', '20130529', 30, 'MEM003', 35, 'Sedative')
, ('InsureCo', '20130529', 30, 'MEM003', 45, 'Sedative')
select memberid,datefilled,SUM(strength) as [Strength sum]
from #MemberInfo
where memberid = 'MEM003' -- or whatever, could be a parameter
group by memberid,DateFilled
order by Memberid,DateFilled
drop table #MemberInfo
【讨论】:
我遇到的问题是,我并不是每天都充满药物。我有一个开始日期和天数。我想为每个成员每天有一个处方创建一行(并为他们的所有处方做同样的事情)。然后我会总结每天所有药物的强度。如果有帮助的话,所有的药物都将属于同一类别,并且强度将是等效剂量,这意味着我可以总结它们。 @KennyG:你不断增加人们给你的每个答案的要求。而不是这样做,edit您的问题,以便人们在尝试发布答案时确切地知道您的要求是什么。我们无法击中移动目标。 @KennyG: ...当我们无法预测它的下一步行动时。【参考方案2】:这是一个示例,说明如何使用 CTE
构建日历并使用 OVER(PARTION BY)
进行聚合
查询:
-- Declare a Start and End Date required to build a calendar
DECLARE @StartDate DATETIME = '2013-01-01'
DECLARE @EndDate DATETIME = '2015-01-01'
-- Build out a Day/Quarter Calendar
;WITH Calendar ([Date], [Quarter]) AS (
SELECT @StartDate, 1
UNION ALL
SELECT [Date] + 1, (DATEDIFF(m, @StartDate, [Date] + 1) / 3) + 1
FROM Calendar
WHERE [Date] + 1 < @EndDate
)
-- Build Result Set
SELECT ProgramName,
DateFilled,
DaySupply,
MemberID,
Strength,
Quarter,
SUM(Strength) OVER(PARTITION BY ProgramName, DaySupply, MemberID, Quarter) AS QuarterlyTotal,
AVG(Strength) OVER(PARTITION BY ProgramName, DaySupply, MemberID, Quarter) AS QuarterlyAverage
FROM #MemberInfo MI
JOIN Calendar C ON MI.DateFilled = C.[Date]
ORDER BY MemberID, DateFilled
OPTION (MAXRECURSION 0)
测试数据:
create table #MemberInfo
(ProgramName varchar(255),
DateFilled datetime,
DaySupply integer,
MemberID varchar(255),
Strength integer,
Tradename varchar(255));
INSERT INTO #MemberInfo
Values
--MEM001
--Q1
('InsureCo', '20130112', 30, 'MEM001', 10, 'Sedative')
,('InsureCo', '20130129', 30, 'MEM001', 20, 'Sedative')
,('InsureCo', '20130401', 30, 'MEM001', 20, 'Sedative')
--Q2
,('InsureCo', '20130529', 30, 'MEM001', 30, 'Sedative')
,('InsureCo', '20130429', 30, 'MEM001', 20, 'Sedative')
,('InsureCo', '20130401', 30, 'MEM001', 20, 'Sedative')
--Q3
,('InsureCo', '20130829', 30, 'MEM001', 30, 'Sedative')
--MEM002
--Q1
,('InsureCo', '20130112', 30, 'MEM002', 10, 'Sedative')
,('InsureCo', '20130129', 30, 'MEM002', 20, 'Sedative')
,('InsureCo', '20130401', 30, 'MEM002', 20, 'Sedative')
--Q2
,('InsureCo', '20130529', 30, 'MEM002', 30, 'Sedative')
,('InsureCo', '20130429', 30, 'MEM002', 20, 'Sedative')
,('InsureCo', '20130401', 30, 'MEM002', 20, 'Sedative')
--Q3
,('InsureCo', '20130829', 30, 'MEM002', 30, 'Sedative')
--Q4
,('InsureCo', '20131129', 30, 'MEM002', 30, 'Sedative')
结果:
ProgramName DateFilled DaySupply MemberID Strength Quarter QuarterlyTotal QuarterlyAverage
InsureCo 2013-01-12 30 MEM001 10 1 30 15
InsureCo 2013-01-29 30 MEM001 20 1 30 15
InsureCo 2013-04-01 30 MEM001 20 2 90 22
InsureCo 2013-04-01 30 MEM001 20 2 90 22
InsureCo 2013-04-29 30 MEM001 20 2 90 22
InsureCo 2013-05-29 30 MEM001 30 2 90 22
InsureCo 2013-08-29 30 MEM001 30 3 30 30
InsureCo 2013-01-12 30 MEM002 10 1 30 15
InsureCo 2013-01-29 30 MEM002 20 1 30 15
InsureCo 2013-04-01 30 MEM002 20 2 90 22
InsureCo 2013-04-01 30 MEM002 20 2 90 22
InsureCo 2013-04-29 30 MEM002 20 2 90 22
InsureCo 2013-05-29 30 MEM002 30 2 90 22
InsureCo 2013-08-29 30 MEM002 30 3 30 30
InsureCo 2013-11-29 30 MEM002 30 4 30 30
【讨论】:
这适用于季度平均值。对于报告,我需要能够计算金额大于某个截止值(比如说 100)的连续天数。这就是为什么我要尝试每天获取金额。 @KennyG:查看我对 Jerry 回答的评论:***.com/questions/19145340/…【参考方案3】:今晚我玩了一些,我离得更近了:
一些数据:
create TABLE dateranges (drug VARCHAR(5), date_begin DATETIME, numdays integer,strength integer)
INSERT into dateranges values ('DrugA', '2010-01-01', 5, 10);
INSERT into dateranges values ('DrugB', '2008-02-27', 10, 20);
INSERT into dateranges values ('DrugC', '2010-04-26', 3, 20);
INSERT into dateranges values ('DrugD', '2000-02-01', 5, 30);
CTE:
WITH cte (id, d, s)
AS (SELECT tbl.drug AS id
,tbl.date_begin AS d
,tbl.strength AS s
FROM dateranges tbl
WHERE DATEDIFF(DAY, tbl.date_begin, tbl.date_begin+numdays-1) <= 100
UNION ALL
SELECT tbl.drug AS id
,DATEADD(DAY, 1, cte.d) AS d
,tbl.strength as s
FROM cte
INNER JOIN dateranges tbl
ON cte.id = tbl.drug
WHERE cte.d < tbl.date_begin+numdays-1)
SELECT id AS drug
,d AS dates
,s AS strength
FROM cte
ORDER BY id, d, s
结果:
DRUG DATES STRENGTH
DrugA January, 01 2010 00:00:00+0000 10
DrugA January, 02 2010 00:00:00+0000 10
DrugA January, 03 2010 00:00:00+0000 10
DrugA January, 04 2010 00:00:00+0000 10
DrugA January, 05 2010 00:00:00+0000 10
DrugB February, 27 2008 00:00:00+0000 20
DrugB February, 28 2008 00:00:00+0000 20
DrugB February, 29 2008 00:00:00+0000 20
DrugB March, 01 2008 00:00:00+0000 20
DrugB March, 02 2008 00:00:00+0000 20
DrugB March, 03 2008 00:00:00+0000 20
DrugB March, 04 2008 00:00:00+0000 20
DrugB March, 05 2008 00:00:00+0000 20
DrugB March, 06 2008 00:00:00+0000 20
DrugB March, 07 2008 00:00:00+0000 20
DrugC April, 26 2010 00:00:00+0000 20
DrugC April, 27 2010 00:00:00+0000 20
DrugC April, 28 2010 00:00:00+0000 20
DrugD February, 01 2000 00:00:00+0000 30
DrugD February, 02 2000 00:00:00+0000 30
DrugD February, 03 2000 00:00:00+0000 30
DrugD February, 04 2000 00:00:00+0000 30
DrugD February, 05 2000 00:00:00+0000 30
从这里开始,我计划按药物、日期、强度(总和强度)进行分组。我应该能够将这些结果扔到一个临时表中,然后计算超过我提到的阈值的天数。
【讨论】:
以上是关于为一个季度中的每一天创建具有处方金额的日期表的主要内容,如果未能解决你的问题,请参考以下文章
mysql怎么得到时间段每一天,不用表,就是得到一个时间段的每一天的日期