Sql-Server

將值分組到桶中

  • November 15, 2019

我正在查詢,我不確定我目前的方法是否是“最佳”方法。我得到了一個充滿值的表格和一個帶有用於對這些值進行分組的儲存桶的表格。

有 2 種類型的桶:

  • 優先級儲存桶,如果項目適用於它們應該落入此儲存桶並被排除在任何後續儲存桶中的條件。
  • 一個簡單的範圍桶,值應該在一個範圍內。

我設置了一個可以用來測試的簡化版本。此處的[Filter]#tempBUcket用於優先級儲存桶

表定義

create table #TempData([Id] int, [value] int);
create table #TempBucket([Id] int, [FromVal] int,[ToVal] int,[Filter] int);

一些測試數據

INSERT INTO #TempData (Id,value)
   VALUES  (1,1),(2,2),(3,3),(4,4),(5,5),
           (6,6),(7,7),(8,8),(9,9),(10,1),
           (11,2),(12,3),(13,4),(14,5),(15,6),
           (16,7),(17,8),(18,9),(19,10),(20,11);
INSERT INTO #TempBucket(Id,FromVal,ToVal,Filter)
   VALUES  (1,0,3,0),(2,3,6,0),
           (3,6,9,0),(4,9,12,0),
           (5,NULL,NULL,1),(6,NULL,NULL,2);

現在我有這個查詢,它可以工作並給出我想要的結果,但我覺得這可以做得更好、更有效。

WITH filteredData as 
   (SELECT tv.*,COALESCE(tb1.Id,tb2.Id) as BucketId FROM #TempData tv
   LEFT JOIN #TempBucket tb1 --prio bucket join
       ON tb1.Filter IS NOT NULL AND tb1.Filter = tv.Value
   LEFT JOIN #TempBucket tb2 --range bucket join
       ON tb2.Fromval < tv.value AND tv.value <= tb2.ToVal
   )
SELECT Count(fd.value) as count ,BucketId FROM filteredData fd GROUP BY BucketId;

dbfiddle.uk

scan我的解決方案只做 1#TempBucket但它增加了一個額外的sort,我不確定它是否更有效,你應該對大量數據進行測試:

;with cte as
(
select t.*, tb.id as BucketId,
      row_number() over(partition by t.id order by tb.FromVal) as rn
from #TempData t
    join #TempBucket tb 
        on (t.value = tb.filter)  
        or (tb.Fromval < t.value AND t.value <= tb.ToVal)
)
select count(id) as cnt, BucketId
from cte
where rn = 1
group by BucketId;

要優先考慮其中的行,在優先級儲存桶的情況下為空,或者您可以排序priority bucket,我只是不知道是或tb.FromVal``tb.Filter desc``priority bucket``FromVal,ToVal``null``Filter = 0

引用自:https://dba.stackexchange.com/questions/253392