下面的查询是基于一个复杂的视图,视图按我的意愿工作(我不打算包含视图,因为我认为它不会对手头的问题有帮助)。我无法做到的是drugCountsinFamilies
列。我需要它来向我展示每个药物家族distinct drugName
的数量。您可以从第一个screencap看到有三个不同的H3A行。 H3A的drugCountsInFamilies
应为3(有三种不同的H3A药物。)
您可以从第二个屏幕截图中看到正在发生的事情是第一个屏幕截图中的drugCountsInFamilies
正在捕获药物名称列出的行数。
以下是我的问题,对不正确的部分发表评论
select distinct
rx.patid
,d2.fillDate
,d2.scriptEndDate
,rx.drugName
,rx.drugClass
--the line directly below is the one that I can't figure out why it's wrong
,COUNT(rx.drugClass) over(partition by rx.patid,rx.drugclass,rx.drugname) as drugCountsInFamilies
from
(
select
ROW_NUMBER() over(partition by d.patid order by d.patid,d.uniquedrugsintimeframe desc) as rn
,d.patid
,d.fillDate
,d.scriptEndDate
,d.uniqueDrugsInTimeFrame
from DrugsPerTimeFrame as d
)d2
inner join rx on rx.patid = d2.patid
inner join DrugTable as dt on dt.drugClass=rx.drugClass
where d2.rn=1 and rx.fillDate between d2.fillDate and d2.scriptEndDate
and dt.drugClass in ('h3a','h6h','h4b','h2f','h2s','j7c','h2e')
order by rx.patid
如果我尝试在count(rx.drugClass)
子句中添加一个distinct,SSMS就会生气。可以使用窗口函数来完成吗?
答案 0 :(得分:18)
我遇到了这个问题,寻找解决我计算不同值的问题的方法。在寻找答案时,我遇到了post。见最后评论。我测试了它并使用了SQL。它对我来说效果很好,我想我会在这里提供另一种解决方案。
总之,使用DENSE_RANK()
,PARTITION BY
分组列,ORDER BY
ASC
和DESC
对列进行计数:
DENSE_RANK() OVER (PARTITION BY drugClass ORDER BY drugName ASC) +
DENSE_RANK() OVER (PARTITION BY drugClass ORDER BY drugName DESC) - 1 AS drugCountsInFamilies
我将此作为模板用于自己。
DENSE_RANK() OVER (PARTITION BY PartitionByFields ORDER BY OrderByFields ASC ) +
DENSE_RANK() OVER (PARTITION BY PartitionByFields ORDER BY OrderByFields DESC) - 1 AS DistinctCount
我希望这有帮助!
答案 1 :(得分:17)
将count(distinct)
作为Windows功能需要一个技巧。实际上有几个级别的技巧。
因为您的请求实际上非常简单 - 值始终为1,因为rx.drugClass位于分区子句中 - 我将做出假设。假设您想要计算每个独特药物类别的数量。
如果是这样,请执行由patid和drugClass分区的row_number()
。当这是1,在一个patid,然后一个新的drugClass开始。创建一个在这种情况下为1的标志,在所有其他情况下为0。
然后,您只需使用分区子句执行sum
即可获取不同值的数量。
查询(格式化之后我可以阅读它),如下所示:
select rx.patid, d2.fillDate, d2.scriptEndDate, rx.drugName, rx.drugClass,
SUM(IsFirstRowInGroup) over (partition by rx.patid) as NumDrugCount
from (select distinct rx.patid, d2.fillDate, d2.scriptEndDate, rx.drugName, rx.drugClass,
(case when 1 = ROW_NUMBER() over (partition by rx.drugClass, rx.patid order by (select NULL))
then 1 else 0
end) as IsFirstRowInGroup
from (select ROW_NUMBER() over(partition by d.patid order by d.patid,d.uniquedrugsintimeframe desc) as rn,
d.patid, d.fillDate, d.scriptEndDate, d.uniqueDrugsInTimeFrame
from DrugsPerTimeFrame as d
) d2 inner join
rx
on rx.patid = d2.patid inner join
DrugTable dt
on dt.drugClass = rx.drugClass
where d2.rn=1 and rx.fillDate between d2.fillDate and d2.scriptEndDate and
dt.drugClass in ('h3a','h6h','h4b','h2f','h2s','j7c','h2e')
) t
order by patid
答案 2 :(得分:0)
什么是不正确的我认为是使用与窗口功能不同,也许一组在这里更合适
select
rx.patid
,rx.drugName
,rx.drugClass
,COUNT(rx.drugClass) as drugCountsInFamilies
from ...
group by
rx.patid
,rx.drugName
,rx.drugClass
order by rx.patid
答案 3 :(得分:-2)
为什么这样的事情不起作用?
django.db.utils.OperationalError: table firstpage_utilisateur has no column named user_id