【问题标题】:T-SQL Unequal Decile based on totals in another columnT-SQL 不等分基于另一列中的总数
【发布时间】:2018-01-25 13:03:19
【问题描述】:

我没有看到我正在寻找的确切答案。我有一个带有 ID 和两个值的表。我需要将第一个值列从低到高排序,然后根据每个十分位数具有相等(或几乎相等)的总值 2 对列表进行十分位数。这是一个使用四分位数考虑空间的示例:

我有:

ID  value1  value2      
1     2      132        
2     6      182        
3     5      195        
4     8      152        
5     3      132        
6     9      129        
7     3      180        
8     9      120        
9     3      172        
10    6      192        
11    9      177        
12    12     151        

每个四分位数应约为 478.5

按 value1 排序得到这个,但我需要能够分配我的四分位数,每个四分位数约为 478.5。我手动输入了样本四分位数,根据计算可能正确也可能不正确

ID  value1  value2  Qtle    
1     2      132      1 
5     3      132      1 
7     3      180      1 
9     3      172      2 
3     5      195      2 
2     6      182      3 
10    6      192      3 
4     8      152      3 
6     9      129      4 
8     9      120      4 
11    9      177      4 
12   12      151      4 

抱歉格式问题 - 第一篇文章。

编辑 1 - 我想我可能已经解决了,虽然它可能没有它应该的那么优雅

编辑 2 - 在上面添加了示例四分位数并修复了下面的代码以反映四分位数而不是十分位数。还修复了 value2 的总和

SELECT value1
    ,value2
,SUM(value2) OVER (ORDER BY value1 ) CumSum
,CASE
    WHEN SUM(value2) OVER (ORDER BY value1 ) < (Select sum(value2) from table1)/4 Then 1 
   WHEN SUM(value2) OVER (ORDER BY value1 ) < 2 * (Select sum(value2) from 
table1)/4 Then 2 
    WHEN SUM(value2) OVER (ORDER BY value1 ) < 3 * (Select sum(value2) from 
table1)/4 Then 3 
    Else 4 
 End as Quartile
FROM Table1

【问题讨论】:

  • 用您正在使用的数据库标记您的问题。
  • T-SQL ...够了
  • @Black.Jack 是的,但它应该在标签中。
  • 你从哪里得到 396.5 的值?你能指定一个预期的输出吗?
  • 对不起,396.5 是 value2 除以 4 的总和。

标签: sql tsql


【解决方案1】:

我希望我的理解是正确的......

以下是一种通用方法。您可以使用变量指定@TileCount

DECLARE @Table1 TABLE(ID INT,value1 INT,value2 INT);
INSERT INTO @Table1 VALUES      
 (1,2,132)        
,(2,6,182)        
,(3,5,195)        
,(4,8,152)        
,(5,3,132)        
,(6,9,129)        
,(7,3,180)        
,(8,9,120)        
,(9,3,172)        
,(10,6,192)        
,(11,9,177)        
,(12,12,151);

DECLARE @TileCount INT=4;

WITH Sums AS
(
    SELECT TOP (@TileCount) ROW_NUMBER() OVER(ORDER BY (SELECT NULL)) AS TileRank
              ,A.SumTotal
              ,ROW_NUMBER() OVER(ORDER BY (SELECT NULL)) * (A.SumTotal / CAST(@TileCount AS FLOAT)) AS SumPart  
    FROM master..spt_values
    CROSS APPLY(SELECT (SELECT SUM(value2) FROM @Table1) AS SumTotal)AS A
)
,AddCumSum AS
(
    SELECT value1
          ,value2
          ,SUM(value2) OVER (ORDER BY value1) CumSum
     FROM @Table1
)
SELECT AddCumSum.*
      ,A.SumPart
      ,A.TileRank AS Tile
FROM AddCumSum
OUTER APPLY(SELECT TOP 1 * FROM Sums WHERE CumSum<=SumPart ORDER BY TileRank ASC) AS A;

结果

+--------+--------+--------+---------+------+
| value1 | value2 | CumSum | SumPart | Tile |
+--------+--------+--------+---------+------+
| 2      | 132    | 132    | 478,5   | 1    |
+--------+--------+--------+---------+------+
| 3      | 132    | 616    | 957     | 2    |
+--------+--------+--------+---------+------+
| 3      | 180    | 616    | 957     | 2    |
+--------+--------+--------+---------+------+
| 3      | 172    | 616    | 957     | 2    |
+--------+--------+--------+---------+------+
| 5      | 195    | 811    | 957     | 2    |
+--------+--------+--------+---------+------+
| 6      | 182    | 1185   | 1435,5  | 3    |
+--------+--------+--------+---------+------+
| 6      | 192    | 1185   | 1435,5  | 3    |
+--------+--------+--------+---------+------+
| 8      | 152    | 1337   | 1435,5  | 3    |
+--------+--------+--------+---------+------+
| 9      | 120    | 1763   | 1914    | 4    |
+--------+--------+--------+---------+------+
| 9      | 129    | 1763   | 1914    | 4    |
+--------+--------+--------+---------+------+
| 9      | 177    | 1763   | 1914    | 4    |
+--------+--------+--------+---------+------+
| 12     | 151    | 1914   | 1914    | 4    |
+--------+--------+--------+---------+------+

一些解释

CTE Sums 计算一些允许将它们用作命名变量的值。在TOP 子句中使用@TileCountROW_NUMBER()master..spt_values 中选择。这只不过是一张填满了的桌子。我们对这些值不感兴趣,我们只需要它作为基础来获得一个运行数字。

第二个 CTE AddCumSum 返回带有运行总和的结果。

最终的SELECT 找到适合运行总和的最小 TileRank。

【讨论】:

    猜你喜欢
    • 2017-12-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-10-15
    • 2018-04-08
    • 2017-02-24
    • 1970-01-01
    • 2015-02-21
    相关资源
    最近更新 更多