0

我经常发现自己运行查询以获取满足特定标准的人数、该人群中的总人数以及找到满足该标准的百分比。我一直在以同样的方式做一段时间,我想知道 SO 会做什么来解决相同类型的问题。以下是我编写查询的方式:

select m.state_cd
    ,m.injurylevel
    ,COUNT(distinct m.patid) as pplOnRx
    ,x.totalPatientsPerState
    ,round((COUNT(distinct m.patid) /cast(x.totalPatientsPerState as float))*100,2) as percentPrescribedNarcotics
    from members as m
    inner join rx on rx.patid=m.PATID
    inner join DrugTable as dt on dt.drugClass=rx.drugClass
    inner join 
    (
        select m2.state_cd, m2.injurylevel, COUNT(distinct m2.patid) as totalPatientsPerState
            from members as m2
            inner join rx on rx.patid=m2.PATID
            group by m2.STATE_CD,m2.injuryLevel
    ) x on x.state_cd=m.state_cd and m.injuryLevel=x.injurylevel
    where drugText like '%narcotics%'
    group by m.state_cd,m.injurylevel,x.totalPatientsPerState
    order by m.STATE_CD,m.injuryLevel

在此示例中,并非出现在members表格中的每个人都在rx表格中。派生表确保所有 in的人都rxmembers没有条件的情况下drugText like narcotics。从我玩过的东西来看,该over(partition by子句似乎可以在这里工作。我不知道是不是这样,在我看来就是这样。其他人将如何解决这个问题?

结果:

在此处输入图像描述

4

1 回答 1

2

这正是 MDX 和 SSAS 的设计目的。如果您坚持在 SQL 中执行此操作(这没有错),您是否在寻求一种具有更好性能的方法?在这种情况下,这将取决于表的索引方式、tempdb 速度,以及表是否已分区,那么也取决于。

此外,不同的计数将成为更大的性能影响之一。谓词中的like '%narcotics%'in 将强制进行全表扫描,应该不惜一切代价避免(这可以是数据模型中的整数键吗?)

要回答您的问题,不确定窗口 ( over partition by) 是否会表现得更好。我会对其进行测试并查看,但查询没有任何“错误”。

您可以使用 group by 或这两者的组合将 count distinct 重写为虚拟表或临时表。

为了说明,这是一个窗口存根,您可以扩展为相同的查询:

select a.state_cd,a.injurylevel,a.totalpatid, count(*) over (partition by a.state_cd, a.injurylevel)
from
(select state_cd,injurylevel,count(*) as totalpatid, count(distinct patid) as patid 
from
#members
group by state_cd,injurylevel
)  a

明白我说的没有那么有帮助是什么意思吗?再说一次,有时稍微重写查询可以通过选择更好的执行计划来提高性能,但与其在黑暗中冒险,我会首先找到您所拥有的查询中的瓶颈,因为您已经花时间编写它。

于 2012-11-12T08:01:09.913 回答