簡體   English   中英

Window 函數對不同的記錄進行計數

[英]Window functions to count distinct records

下面的查詢基於一個復雜的視圖,該視圖按我的意願工作(我不打算包含該視圖,因為我認為它不會幫助解決手頭的問題)。 我不能正確的是drugCountsinFamilies列。 我需要它來向我顯示每個葯物系列的distinct drugName的數量。 您可以從第一個屏幕截圖中看到有三個不同的 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 會發瘋。 可以使用 window 函數來完成嗎?

我遇到了這個問題,尋找解決我計算不同值的問題的方法。 在尋找答案時,我發現了這篇文章 見最后評論。 我測試了它並使用了SQL。 它對我來說真的很好,我想我會在這里提供另一個解決方案。

總之,使用DENSE_RANK()PARTITION BY分組列, ORDER BY ASCDESC對列進行計數:

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

我希望這有幫助!

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

我認為您嘗試做的是將其作為窗口函數:

COUNT(DISTINCT rx.drugName) over(partition by rx.patid,rx.drugclass) as drugCountsInFamilies

哪個 SQL 抱怨。 但是你可以這樣做:

SELECT 
rx.patid
, rx.drugName
, rx.drugClass
, (SELECT COUNT(DISTINCT rx2.drugName) FROM rx rx2 WHERE rx2.drugClass = rx.DrugClass AND rx2.patid = rx.patid) As drugCountsInFamilies
FROM rx
...

如果表很大,那么最好將索引放在其中一列(例如 patid)上,這樣嵌套查詢就不會消耗大量資源。

select max(dense_rank() over (order by name desc partition by family)) over (partition by family) 

這能行嗎?

為什么這樣的事情不起作用?

SELECT 
   IDCol_1
  ,IDCol_2
  ,Count(*) Over(Partition By IDCol_1, IDCol_2 order by IDCol_1) as numDistinct
FROM Table_1

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM