如何将SQL结果计数并分组到自定义分组类别中?

huangapple go评论66阅读模式
英文:

How to Count & Group SQL Results into Custom Group Categories?

问题

抱歉,我只返回翻译好的部分,不包括代码。以下是您的内容的翻译:

我在一家制造电子传感器的工厂工作。
我们按批次制造这些传感器 - 每个批次有10,000个传感器。
截止到今天,我们已经制造了30,000批次。(所以总共处理了3亿个传感器)

我们对每个传感器进行测量,测量传感器的尾部弯曲程度。
如果尾部没有弯曲(与地板平行),值为0。
如果尾部向天花板垂直弯曲成90度,值为1。
如果尾部向地板垂直弯曲成90度,值为-1。

这些测量通常不是整数,而是带有8位小数。
例如,0.18345171

这些值被写入名为SENSOR_INSPECTIONS的Oracle数据库表中。
当表按特定批次号进行筛选时,看起来如下。

| 传感器编号 | 值 |
| 1 | 0.33827491 |
| 2 | 0.41810703 |

是否有办法编写一个SQL语句,根据我的自定义类别对值进行计数和分组?

在这个示例中,我想计算等于0的值的数量,大于0的值的数量以及小于0的值的数量。

通常情况下,我会编写一个类似下面的SQL函数来执行此操作。
但是,由于有8位小数,这意味着至少可能有1亿个不同的值/类别!

SELECT 值, COUNT(值) as TotalRepetitions
FROM SENSOR_INSPECTIONS
GROUP BY 值;

最终,我想要如下表格:

| 值 | TotalRepetitions |
| 0 | 12567 |
| >0 | 56795 |
| <0 | 23456 |

英文:

(Apologies in advance - I'm not the best writer!

I work in a factory that makes electronic sensors.
We make these sensors in batches - and each batch has 10,000 Sensors.
We've made 30, 000 Lots as of today. (So that's 300 Million Sensors Processed)

We take a measurement for each sensor that measures how much the tail of the Sensor is bending.
If there is no bend in the tail (and it is parallel to the floor), the value is 0.
If the tail bends straight up at 90 degrees towards the ceiling, the value is 1.
And if the tail bends straight down at 90 degrees towards the floor, the value is -1.

The measurements are often not whole numbers and go to 8 decimal places however.
e.g. 0.18345171

The values get written to a table called SENSOR_INSPECTIONS in an Oracle Database.
When the Table is filtered by a specific Lot Number; it looks like the below.

| SENSOR # | VALUE      |
| 1        | 0.33827491 |
| 2        | 0.41810703 |

Is there a way for me to write an SQL Statement, where I perform a count and group the number of values based on my own custom categories?

For this example, I'd like to Count the number of values that equal 0, the number of values greater than 0, and the number of values less than 0.

Normally, I'd write an SQL Function like the below to do this.
But as there is are 8 Decimal places, this means there can be at least 100 Million distinct values/categories!

SELECT VALUE, COUNT(VALUE) as TotalRepetitions
FROM SENSOR_INSPECTIONS
GROUP BY VALUE;

Ultimately, I'd like a Table like the Below:

| Value | TotalRepetitions |
| 0     | 12567            |
| &gt;0    | 56795            |
| &lt;0    | 23456            |

答案1

得分: 3

你可以使用 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
英文:

You can use case expression to get the different groups:

SELECT VALUE_GROUP, COUNT(*) as TotalRepetitions
FROM
(
    SELECT CASE WHEN VALUE &gt; 0 THEN &#39;&gt;0&#39;
                WHEN VALUE &lt; 0 THEN &#39;&lt;0&#39;
                ELSE &#39;0&#39;
           END AS VALUE_GROUP
    FROM SENSOR_INSPECTIONS
)
GROUP BY VALUE_GROUP

答案2

得分: 1

一种选择可能是条件聚合,例如:

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
英文:

One option might be conditional aggregation, e.g.

select 
  sum(case when value = 0 then 1 else 0 end) value_0,
  sum(case when value &gt; 0 then 1 else 0 end) value_positive,
  sum(case when value &lt; 0 then 1 else 0 end) value_negative
from sensor_inspections  

答案3

得分: 1

你可以使用 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 &lt;= 25 UNION ALL
SELECT LEVEL, 0 FROM DUAL CONNECT BY LEVEL &lt;= 20 UNION ALL
SELECT LEVEL, -1 + DBMS_RANDOM.VALUE(0, 1) FROM DUAL CONNECT BY LEVEL &lt;= 23;

输出结果:

SIGN TOTAL_REPETITIONS
1 25
0 20
-1 23

如果你想要为值添加字符串,你可以使用 DECODE 包装它:

SELECT DECODE(SIGN(value), 1, '&gt;0', -1, '&lt;0', 0, '0') AS value,
       COUNT(*) AS total_repetitions
FROM   table_name
GROUP BY SIGN(value)

输出结果:

VALUE TOTAL_REPETITIONS
>0 25
0 20
&lt;0 23

fiddle

英文:

You can use the SIGN function to find out whether the value is positive, zero or negative:

SELECT SIGN(value) AS sign,
       COUNT(*) AS total_repetitions
FROM   table_name
GROUP BY SIGN(value)

Which, for the sample data:

CREATE TABLE table_name (sensor#, value) AS
SELECT LEVEL, +1 - DBMS_RANDOM.VALUE(0, 1) FROM DUAL CONNECT BY LEVEL &lt;= 25 UNION ALL
SELECT LEVEL, 0 FROM DUAL CONNECT BY LEVEL &lt;= 20 UNION ALL
SELECT LEVEL, -1 + DBMS_RANDOM.VALUE(0, 1) FROM DUAL CONNECT BY LEVEL &lt;= 23;

Outputs:

SIGN TOTAL_REPETITIONS
1 25
0 20
-1 23

If you want your strings for the value then you can wrap it in DECODE:

SELECT DECODE(SIGN(value), 1, &#39;&gt;0&#39;, -1, &#39;&lt;0&#39;, 0, &#39;0&#39;) AS value,
       COUNT(*) AS total_repetitions
FROM   table_name
GROUP BY SIGN(value)

Which outputs:

VALUE TOTAL_REPETITIONS
>0 25
0 20
&lt;0 23

fiddle

答案4

得分: 0

使用CASE语句将数据分组为不同的类别,然后根据所需的方法使用SUMCOUNT

测试数据示例:

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;

要么使用每行一个类别:

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;
英文:

Use a case statement to group data into categories, then SUM or COUNT depending on what approach you want.

For test data

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
  
);

Either use one column per category

select sensor_id, 
       SUM(CASE WHEN val = 0 THEN 1 ELSE 0 END) as &quot;0&quot;, 
       SUM(CASE WHEN val &gt; 0 THEN 1 ELSE 0 END) &quot;&gt;0&quot;, 
       SUM(CASE WHEN val &lt; 0 THEN 1 ELSE 0 END) &quot;&lt;0&quot;
FROM test_data GROUP BY sensor_id;

 SENSOR_ID          0         &gt;0         &lt;0
---------- ---------- ---------- ----------
         1          1          3          1
         2          0          0          1

Or one category by row

select sensor_id, 
       CASE WHEN val = 0 THEN &#39;0&#39; WHEN val &lt;0 THEN &#39;&lt;0&#39; ELSE &#39;&gt;0&#39; END as my_category,
       COUNT(*)
FROM test_data GROUP BY sensor_id, CASE WHEN val = 0 THEN &#39;0&#39; WHEN val &lt;0 THEN &#39;&lt;0&#39; ELSE &#39;&gt;0&#39; END;

 SENSOR_ID MY   COUNT(*)
---------- -- ----------
         1 &lt;0          1
         1 0           1
         1 &gt;0          3
         2 &lt;0          1

huangapple
  • 本文由 发表于 2023年6月12日 19:09:39
  • 转载请务必保留本文链接:https://go.coder-hub.com/76456073.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定