如何使用 SQL 聚合一些概念类的值?
Posted
技术标签:
【中文标题】如何使用 SQL 聚合一些概念类的值?【英文标题】:How do I aggregate values respect to some conceptual classes with SQL? 【发布时间】:2016-10-10 01:48:11 【问题描述】:我要解决的问题是一些值的分类,以便通过 SQL 提取一些知识。
将要提出的sql方案可以应用于由少数类组成的分类系统
我们将考虑一个简单的案例,通过分层排序进行聚合。特别是我们的分类 系统将由几个班级组成,每个班级对应一定天数的班级 小于不同数量。
类的数量应该非常有限。
例如:所有天数小于 7 的班级,所有天数小于 6 的班级, 由所有天数少于五天组成的班级,以此类推……
我受到堆栈溢出问题的启发..Aggregation of Data
我们要使用的sql是mysql dbms上实现的版本。 对于答案中报告的示例,您可以使用 SQL Fiddle:http://sqlfiddle.com
【问题讨论】:
【参考方案1】:基于 SQL 中的分类系统的值聚合
要处理此类问题,在我们问题中定义的约束条件下,我们可以开始考虑我们的 由一些表记录组成的分类系统,代表我们将考虑的类 执行我们的计算,我们的参考系统。
我们的目标是根据我们的类计算一些值,对于每个类我们想知道某事的百分比..
那么,让我们创建我们的类表..
表“类”的问题。
Class Reference_Score
----------------------------
1 1800
3 1800
5 1800
7 1800
此表的每条记录代表所有值小于字段“Class”的值的类:
..然后是我们的“分数”
some_order order_score
--------------------------
1 90
3 80
4 560
6 980
7 1050
好的..我们想知道每个班级的百分比分数,即所有分数总和的关系 属于具有分配给该类的分数的类,我们的参考分数:
percentage_score = ( SUM(order_score)/Reference_Score ) * 100
ok,开始吧..(后面的sql是MySql Dbms的实现)
1.第一件事是按顺序为我们分数的每个值分配标志:
select
Scores.some_order, Scores.order_score,
case when Scores.some_order <= 7 then '1_7' else '' end seven,
case when Scores.some_order <= 6 then '1_6' else '' end six,
case when Scores.some_order <= 5 then '1_5' else '' end five,
case when Scores.some_order <= 4 then '1_4' else '' end four,
case when Scores.some_order <= 3 then '1_3' else '' end three,
case when Scores.some_order <= 2 then '1_2' else '' end two,
case when Scores.some_order <= 1 then '1_1' else '' end one
FROM Scores
this is the result:
| some_order | order_score | seven | six | five | four | three | two | one |
|------------|-------------|-------|-----|------|------|-------|-----|-----|
| 1 | 90 | 1_7 | 1_6 | 1_5 | 1_4 | 1_3 | 1_2 | 1_1 |
| 3 | 80 | 1_7 | 1_6 | 1_5 | 1_4 | 1_3 | | |
| 4 | 560 | 1_7 | 1_6 | 1_5 | 1_4 | | | |
| 6 | 980 | 1_7 | 1_6 | | | | | |
| 7 | 1050 | 1_7 | | | | | | |
----------------------------------------------------------------------------
2.现在,我们可以开始计算每个分数的总和,并将这个总和放在计算字段中,每个计算字段代表我们问题的一个类别,我们将得到的表格记录,代表同质类别的分数 :
select
case when Scores_Flagged.seven = '1_7' then sum(Scores_Flagged.order_score) else 0 end tot_seven,
case when Scores_Flagged.six = '1_6' then sum(Scores_Flagged.order_score) else 0 end tot_six,
case when Scores_Flagged.five = '1_5' then sum(Scores_Flagged.order_score) else 0 end tot_five,
case when Scores_Flagged.four = '1_4' then sum(Scores_Flagged.order_score) else 0 end tot_four,
case when Scores_Flagged.three = '1_3' then sum(Scores_Flagged.order_score) else 0 end tot_three,
case when Scores_Flagged.two = '1_2' then sum(Scores_Flagged.order_score) else 0 end tot_two,
case when Scores_Flagged.one = '1_1' then sum(Scores_Flagged.order_score) else 0 end tot_one
from
(
select
Scores.some_order, Scores.order_score,
case when Scores.some_order <= 7 then '1_7' else '' end seven,
case when Scores.some_order <= 6 then '1_6' else '' end six,
case when Scores.some_order <= 5 then '1_5' else '' end five,
case when Scores.some_order <= 4 then '1_4' else '' end four,
case when Scores.some_order <= 3 then '1_3' else '' end three,
case when Scores.some_order <= 2 then '1_2' else '' end two,
case when Scores.some_order <= 1 then '1_1' else '' end one
FROM Scores
) Scores_Flagged
group by seven, six, five, four, three, two, one
| tot_seven | tot_six | tot_five | tot_four | tot_three | tot_two | tot_one |
|-----------|---------|----------|----------|-----------|---------|---------|
| 1050 | 0 | 0 | 0 | 0 | 0 | 0 |
| 980 | 980 | 0 | 0 | 0 | 0 | 0 |
| 560 | 560 | 560 | 560 | 0 | 0 | 0 |
| 80 | 80 | 80 | 80 | 80 | 0 | 0 |
| 90 | 90 | 90 | 90 | 90 | 90 | 90 |
-----------------------------------------------------------------------------
3.此时,让我们获取同质类的总分,它们将成为我们计算的基础:
select
sum(Scores_by_Omogeneous_Classes.tot_seven) tot_seven,
sum(Scores_by_Omogeneous_Classes.tot_six) tot_six,
sum(Scores_by_Omogeneous_Classes.tot_five) tot_five,
sum(Scores_by_Omogeneous_Classes.tot_four) tot_four,
sum(Scores_by_Omogeneous_Classes.tot_three) tot_three,
sum(Scores_by_Omogeneous_Classes.tot_two) tot_two,
sum(Scores_by_Omogeneous_Classes.tot_one) tot_one
from
(
select
case when Scores_Flagged.seven = '1_7' then sum(Scores_Flagged.order_score) else 0 end tot_seven,
case when Scores_Flagged.six = '1_6' then sum(Scores_Flagged.order_score) else 0 end tot_six,
case when Scores_Flagged.five = '1_5' then sum(Scores_Flagged.order_score) else 0 end tot_five,
case when Scores_Flagged.four = '1_4' then sum(Scores_Flagged.order_score) else 0 end tot_four,
case when Scores_Flagged.three = '1_3' then sum(Scores_Flagged.order_score) else 0 end tot_three,
case when Scores_Flagged.two = '1_2' then sum(Scores_Flagged.order_score) else 0 end tot_two,
case when Scores_Flagged.one = '1_1' then sum(Scores_Flagged.order_score) else 0 end tot_one
from
(
select
Scores.some_order, Scores.order_score,
case when Scores.some_order <= 7 then '1_7' else '' end seven,
case when Scores.some_order <= 6 then '1_6' else '' end six,
case when Scores.some_order <= 5 then '1_5' else '' end five,
case when Scores.some_order <= 4 then '1_4' else '' end four,
case when Scores.some_order <= 3 then '1_3' else '' end three,
case when Scores.some_order <= 2 then '1_2' else '' end two,
case when Scores.some_order <= 1 then '1_1' else '' end one
FROM Scores
) Scores_Flagged
group by seven, six, five, four, three, two, one
)Scores_by_Omogeneous_Classes
| tot_seven | tot_six | tot_five | tot_four | tot_three | tot_two | tot_one |
|-----------|---------|----------|----------|-----------|---------|---------|
| 2760 | 1710 | 730 | 730 | 170 | 90 | 90 |
-----------------------------------------------------------------------------
4.最后,让我们按每个类评估我们的预期值(在本例中为百分比)::
select
Classes.Class,
case
when Classes.Class = 7
then cast((Total_Scores_by_Omogeneous_Classes.tot_seven/Classes.Reference_Score) * 100 as decimal(5,2))
when Classes.Class = 6
then cast((Total_Scores_by_Omogeneous_Classes.tot_six/Classes.Reference_Score) * 100 as decimal(5,2))
when Classes.Class = 5
then cast((Total_Scores_by_Omogeneous_Classes.tot_five/Classes.Reference_Score) * 100 as decimal(5,2))
when Classes.Class = 4
then cast((Total_Scores_by_Omogeneous_Classes.tot_four/Classes.Reference_Score) * 100 as decimal(5,2))
when Classes.Class = 3
then cast((Total_Scores_by_Omogeneous_Classes.tot_three/Classes.Reference_Score) * 100 as decimal(5,2))
when Classes.Class = 2
then cast((Total_Scores_by_Omogeneous_Classes.tot_two/Classes.Reference_Score) * 100 as decimal(5,2))
when Classes.Class = 1
then cast((Total_Scores_by_Omogeneous_Classes.tot_one/Classes.Reference_Score) * 100 as decimal(5,2))
else 0
end Percentage_Score
from Classes
inner join
(
select
sum(Scores_by_Omogeneous_Classes.tot_seven) tot_seven,
sum(Scores_by_Omogeneous_Classes.tot_six) tot_six,
sum(Scores_by_Omogeneous_Classes.tot_five) tot_five,
sum(Scores_by_Omogeneous_Classes.tot_four) tot_four,
sum(Scores_by_Omogeneous_Classes.tot_three) tot_three,
sum(Scores_by_Omogeneous_Classes.tot_two) tot_two,
sum(Scores_by_Omogeneous_Classes.tot_one) tot_one
from
(
select
case when Scores_Flagged.seven = '1_7' then sum(Scores_Flagged.order_score) else 0 end tot_seven,
case when Scores_Flagged.six = '1_6' then sum(Scores_Flagged.order_score) else 0 end tot_six,
case when Scores_Flagged.five = '1_5' then sum(Scores_Flagged.order_score) else 0 end tot_five,
case when Scores_Flagged.four = '1_4' then sum(Scores_Flagged.order_score) else 0 end tot_four,
case when Scores_Flagged.three = '1_3' then sum(Scores_Flagged.order_score) else 0 end tot_three,
case when Scores_Flagged.two = '1_2' then sum(Scores_Flagged.order_score) else 0 end tot_two,
case when Scores_Flagged.one = '1_1' then sum(Scores_Flagged.order_score) else 0 end tot_one
from
(
select
Scores.some_order, Scores.order_score,
case when Scores.some_order <= 7 then '1_7' else '' end seven,
case when Scores.some_order <= 6 then '1_6' else '' end six,
case when Scores.some_order <= 5 then '1_5' else '' end five,
case when Scores.some_order <= 4 then '1_4' else '' end four,
case when Scores.some_order <= 3 then '1_3' else '' end three,
case when Scores.some_order <= 2 then '1_2' else '' end two,
case when Scores.some_order <= 1 then '1_1' else '' end one
FROM Scores
) Scores_Flagged
group by seven, six, five, four, three, two, one
)Scores_by_Omogeneous_Classes
) Total_Scores_by_Omogeneous_Classes
5.我们有我们参加的结果:
| Class | Percentage_Score |
|-------|------------------|
| 1 | 5 |
| 3 | 9.44 |
| 5 | 40.56 |
| 7 | 153.33 |
----------------------------
我们还可以为相同的课程添加多个参考分数,因此可以根据更多参考分数产生多个百分比:
for example:
Class Reference_Score
----------------------------
1 1800
3 1800
5 1800
7 1800
1 3600
3 3600
5 3600
7 3600
--------------------------
| Class | Percentage_Score |
|-------|------------------|
| 1 | 5 |
| 3 | 9.44 |
| 5 | 40.56 |
| 7 | 153.33 |
| 1 | 2.5 |
| 3 | 4.72 |
| 5 | 20.28 |
| 7 | 76.67 |
----------------------------
【讨论】:
以上是关于如何使用 SQL 聚合一些概念类的值?的主要内容,如果未能解决你的问题,请参考以下文章
如何在一个值之前的值上计算聚合函数 COUNT(DISTINCT)?