你需要的是基本上用于
直方图数据。
你会在x轴上有年龄(或年龄范围),在y轴上有计数n(或频率)。
简单来说,你可以像你已经描述的那样,只需计算每个不同年龄值的数量。
SELECT age, count(*)
FROM tbl
GROUP BY age
当x轴上存在太多不同的值时,我们可能希望创建分组(或聚类或桶)。在您的情况下,您按常量范围为10进行分组。
我们可以避免为每个范围编写一个WHEN ... THEN行-如果不是年龄,则可能有数百个。相反,@MatthewFlaschen的方法因@NitinMidha提到的原因而更可取。
现在让我们构建SQL...
首先,我们需要将年龄分成10个范围组,如下所示:
0-9
10-19
20 - 29
等等。
这可以通过将年龄列除以10,然后计算结果的FLOOR来实现:
FLOOR(age/10)
"FLOOR返回小于或等于n的最大整数"
http://docs.oracle.com/cd/E11882_01/server.112/e26088/functions067.htm#SQLRF00643
然后我们用该表达式替换原始的SQL中的age:
SELECT FLOOR(age/10), count(*)
FROM tbl
GROUP BY FLOOR(age/10)
这样是可以的,但我们还不能看到范围。相反,我们只能看到计算出来的底部值,它们是0、1、2 ... n
。
要获取实际的下限,我们需要再次将其乘以10,这样我们就得到了0、10、20 ... n
:
FLOOR(age/10) * 10
我们还需要每个范围的上限,即下限加10再减1。
FLOOR(age/10) * 10 + 10 - 1
最后,我们将它们连接成一个字符串,像这样:
TO_CHAR(FLOOR(age/10) * 10) || '-' || TO_CHAR(FLOOR(age/10) * 10 + 10 - 1)
这将创建'0-9','10-19','20-29'
等。
现在我们的SQL代码如下:
SELECT
TO_CHAR(FLOOR(age/10) * 10) || ' - ' || TO_CHAR(FLOOR(age/10) * 10 + 10 - 1),
COUNT(*)
FROM tbl
GROUP BY FLOOR(age/10)
最后,应用排序和良好的列别名:
SELECT
TO_CHAR(FLOOR(age/10) * 10) || ' - ' || TO_CHAR(FLOOR(age/10) * 10 + 10 - 1) AS range,
COUNT(*) AS frequency
FROM tbl
GROUP BY FLOOR(age/10)
ORDER BY FLOOR(age/10)
然而,在更复杂的场景中,这些范围可能不会被分组为大小为10的恒定块,而需要进行动态聚类。
Oracle包括更高级的直方图函数,详见http://docs.oracle.com/cd/E16655_01/server.121/e15858/tgsql_histo.htm#TGSQL366
感谢@MatthewFlaschen提供的方法; 我只解释了细节。