SQL跨行分配值

时间:2015-08-21 23:28:59

标签: sql sql-server sql-server-express

SQL不是我的强项,我需要帮助。我正在尝试传播我从一个表中选择多行的Max值。假设我从最大值5(B.MaxVal = 5)开始,我有3行要拆分(有3个相同的B.bId个实例)。

我想取值5并得出每个实例的结果。如果我们取5的值并除以3,我将得到一个不好的浮动。相反,我希望5在B.bId

的3个实例中分配为2,2,1
select distinct 
    A.aId,  B.bId, B.MaxVal, 
    B.MaxVal / Count(B.bId) OVER(PARTITION BY B.bId) AS 'AVG' 
from 
    CPN
inner join 
    PN on CPN.aId = PN.id
inner join 
    A on A.aId = CPN.aId
left join 
    B on PN.bId = B.bId
where 
    (some search param)
group by 
    A.aId,  B.bId, B.MaxVal

A和B是不同的表格。

1 个答案:

答案 0 :(得分:0)

编辑:已修改为使用FLOOR()功能,并根据您的评论更改了不平等。

我会尝试这样的事情:

FLOOR(B.MaxVal / COUNT(B.bId) OVER (PARTITION BY B.bId)) 
+ CASE 
    WHEN ROW_NUMBER() OVER (PARTITION BY b.bId ORDER BY b.bId) <= (B.MaxVal % COUNT(B.bId) OVER (PARTITION BY B.bId)) THEN 1 
    ELSE 0 
END as "DISTRIBUTED_AVG"

第一位是你已经在做的分工。 SQL Server also serves as the truncate function中的 ROUND()ROUND(<expression>,0,1)将截断小数点处的值。使用FLOOR()函数。

接下来的一点很复杂。您的描述基本上是我们需要按计数展开最大值的其余部分。那么,除法的余数是模函数。所以,我们知道我们可能需要使用它。那是(B.MaxVal % COUNT(B.bId) OVER (PARTITION BY B.bId))的原因。

接下来,我们需要知道我们用尽了多少剩余部分。因为我们只处理剩余部分,所以我们知道我们永远不需要为任何值提供多个额外项目。这也意味着我们将消费&#34;其余的以每行1的速度。因此,我们需要知道我们所在的组中的哪一行。为此,我使用了ROW_NUMBER()函数。它的分区与COUNT()相同,因此它将具有相同的分组。你唯一想要改变的是ORDER BY;我刚选了一些东西。基本上,我们知道当剩余部分等于或小于我们经历过的行数时,我们就会得到余数,好吧,剩下的。

我觉得我的数学略有偏差,或者我错过了一些东西,但是,因为我现在有点累了。我鼓励你看看每个人都明白它在做什么:

SELECT DISTINCT A.aId,
    B.bId,
    B.MaxVal,
    B.MaxVal / Count(B.bId) OVER (PARTITION BY B.bId) AS 'AVG'
    FLOOR(B.MaxVal / COUNT(B.bId) OVER (PARTITION BY B.bId)), 
    ROW_NUMBER() OVER (PARTITION BY b.bId ORDER BY b.bId), 
    B.MaxVal % COUNT(B.bId) OVER (PARTITION BY B.bId),
    ROUND(B.MaxVal / COUNT(B.bId) OVER (PARTITION BY B.bId),0,1) 
    + CASE 
        WHEN ROW_NUMBER() OVER (PARTITION BY b.bId ORDER BY b.bId) <= (B.MaxVal % COUNT(B.bId) OVER (PARTITION BY B.bId)) THEN 1 
        ELSE 0 
    END as "DISTRIBUTED_AVG"
FROM [...]