22

以下のクエリは複雑なビューに基づいており、ビューは希望どおりに機能します (当面の質問に役立つとは思わないため、ビューを含めるつもりはありません)。私が正しく理解できないのは、drugCountsinFamilies列です。distinct drugName各ドラッグファミリーの の数を表示する必要があります。最初のスクリーン キャプチャから、3 つの異なる H3A 行があることがわかります。drugCountsInFamiliesH3Aのは 3 にする必要があります (3 つの異なる H3A 薬があります。)

ここに画像の説明を入力

2 番目のスクリーン キャプから、最初のスクリーン キャプで何が起こっているかが分かります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

句に個別を追加しようとすると、SSMS が怒ってしまいcount(rx.drugClass)ます。ウィンドウ関数を使用して実行できますか?

4

4 に答える 4

27

Windows関数count(distinct)として実行するには、トリックが必要です。実際には、いくつかのレベルのトリックです。

あなたの要求は実際には非常に単純であるため、rx.drugClass がパーティショニング節にあるため、値は常に 1 です。仮定を行います。patid ごとの一意の薬物クラスの数を数えたいとしましょう。

その場合は、row_number()patid と DrugClass でパーティション分割を行います。これが 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
于 2012-11-20T20:19:23.660 に答える