(提前道歉 - 我不是最好的作家!
测量结果通常不是整数,而是精确到小数点后 8 位。 例如0.18345171
这些值被写入 Oracle 数据库中名为 INSPECTIONS 的表中。 当表格按特定批号过滤时;看起来像下面这样。
| SENSOR # | VALUE |
| 1 | 0.33827491 |
| 2 | 0.41810703 |
有没有办法让我编写 SQL 语句,根据我自己的自定义类别执行计数并分组值的数量?
对于这个例子,我想计算等于 0 的值的数量、大于 0 的值的数量和小于 0 的值的数量。
通常,我会编写如下所示的 SQL 函数来执行此操作。 但由于有 8 位小数,这意味着至少可以有 1 亿个不同的值/类别!
SELECT VALUE, COUNT(VALUE) as TotalRepetitions
FROM INSPECTIONS
GROUP BY VALUE;
最终,我想要一张如下所示的表格:
| Value | TotalRepetitions |
| 0 | 12567 |
| >0 | 56795 |
| <0 | 23456 |
您可以使用
case
表达式 来获取不同的组:
SELECT VALUE_GROUP, COUNT(*) as TotalRepetitions
FROM
(
SELECT CASE WHEN VALUE > 0 THEN '>0'
WHEN VALUE < 0 THEN '<0'
ELSE '0'
END AS VALUE_GROUP
FROM SENSOR_INSPECTIONS
)
GROUP BY VALUE_GROUP
一个选项可能是条件聚合,例如
select
sum(case when value = 0 then 1 else 0 end) value_0,
sum(case when value > 0 then 1 else 0 end) value_positive,
sum(case when value < 0 then 1 else 0 end) value_negative
from sensor_inspections
您可以使用
SIGN
函数来查看该值是正数、零还是负数:
SELECT SIGN(value) AS sign,
COUNT(*) AS total_repetitions
FROM table_name
GROUP BY SIGN(value)
对于样本数据:
CREATE TABLE table_name (sensor#, value) AS
SELECT LEVEL, +1 - DBMS_RANDOM.VALUE(0, 1) FROM DUAL CONNECT BY LEVEL <= 25 UNION ALL
SELECT LEVEL, 0 FROM DUAL CONNECT BY LEVEL <= 20 UNION ALL
SELECT LEVEL, -1 + DBMS_RANDOM.VALUE(0, 1) FROM DUAL CONNECT BY LEVEL <= 23;
输出:
标志 | TOTAL_REPETITIONS |
---|---|
1 | 25 |
0 | 20 |
-1 | 23 |
如果您想要字符串作为值,那么您可以将其包装在
DECODE
:
SELECT DECODE(SIGN(value), 1, '>0', -1, '<0', 0, '0') AS value,
COUNT(*) AS total_repetitions
FROM table_name
GROUP BY SIGN(value)
哪个输出:
价值 | TOTAL_REPETITIONS |
---|---|
>0 | 25 |
0 | 20 |
<0 | 23 |
使用 case 语句将数据分组,然后根据您想要的方法使用
SUM
或 COUNT
。
测试数据
CREATE TABLE test_data (sensor_id, val) AS
(
select 1, 0.1 from dual UNION ALL
select 1, 0.12 from dual UNION ALL
select 1, 0.198 from dual UNION ALL
select 1, -0.2 from dual UNION ALL
select 1, 0 from dual UNION ALL
select 2, -1 from dual
);
每个类别使用一列
select sensor_id,
SUM(CASE WHEN val = 0 THEN 1 ELSE 0 END) as "0",
SUM(CASE WHEN val > 0 THEN 1 ELSE 0 END) ">0",
SUM(CASE WHEN val < 0 THEN 1 ELSE 0 END) "<0"
FROM test_data GROUP BY sensor_id;
SENSOR_ID 0 >0 <0
---------- ---------- ---------- ----------
1 1 3 1
2 0 0 1
或按行一个类别
select sensor_id,
CASE WHEN val = 0 THEN '0' WHEN val <0 THEN '<0' ELSE '>0' END as my_category,
COUNT(*)
FROM test_data GROUP BY sensor_id, CASE WHEN val = 0 THEN '0' WHEN val <0 THEN '<0' ELSE '>0' END;
SENSOR_ID MY COUNT(*)
---------- -- ----------
1 <0 1
1 0 1
1 >0 3
2 <0 1