1

如何根据值分配类别?

例如,我有一个值从 1 到 200 的表。我如何为每条记录分配一个类别,例如 1-5、6-10、11-15 等。

我可以使用下面的方法来做到这一点,但这似乎是一个糟糕的解决方案。

抱歉,这可能是非常基本的,但我不知道它叫什么,谷歌搜索桶(正如我们公司所说的那样)没有带来任何结果。

谢谢你

SELECT DISTINCT CountOfSA,
 CASE
              WHEN CountOfSA BETWEEN 1 AND 5 THEN
                   '1-5'
              WHEN CountOfSA BETWEEN 6 AND 10 THEN
                   '6-10'
              WHEN CountOfSA BETWEEN 11 AND 15 THEN
                   '11-15'
              WHEN CountOfSA BETWEEN 16 AND 20 THEN
                   '16-20'
              WHEN CountOfSA BETWEEN 21 AND 25 THEN
                   '21-25'
              WHEN CountOfSA BETWEEN 26 AND 30 THEN
                   '26-30'
         END
              AS diff
              FROM NR_CF_212
4

3 回答 3

2

看看WIDTH_BUCKET函数。这将范围划分为相等大小的间隔,并为每个间隔分配一个桶号。

with x as (
    select CountOfSA, 
    width_bucket(CountOfSA, 1, 200, 40) bucket_
    from NR_CF_212
    )
select CountOfSA, 
       cast(1 + (bucket_ - 1)*5 as varchar2(4)) ||
       '-' ||
       cast( bucket_*5 as varchar2(4)) diff
from x
order by CountOfSA;

演示在这里

于 2013-10-23T05:15:50.407 回答
0

我会将范围值和描述放入单独的表中,特别是如果您打算将它们用于未来的查询、视图等。此外,根据需要更容易更改范围或描述。例如:

create table sales_ranges
(
low_val number not null,
high_val number not null,
range_desc varchar2(100) not null
)
cache;

insert into sales_ranges values (0,1000,'$0-$1k');
insert into sales_ranges values (1001,10000,'$1k-$10k');
insert into sales_ranges values (10001,100000,'$10k-$100k');
insert into sales_ranges values (100001,1000000,'$100k-$1mm');
insert into sales_ranges values (1000001,10000000,'$1mm-$10mm');
insert into sales_ranges values (10000001,100000000,'$10mm-$100mm');
commit;


create table sales
(
id number,
total_sales number
);

insert into sales(id, total_sales) 
-- some random values for testing
select level, trunc(dbms_random.value(1,10000000))
from dual
connect by level <= 100;

commit;

select id, total_sales, range_desc
from sales s
left outer join sales_ranges sr 
  on (s.total_sales between sr.low_val and sr.high_val)
order by s.id
;

输出(仅前 3 行):

ID  TOTAL_SALES RANGE_DESC
1   5122380 $1mm-$10mm
2   347726  $100k-$1mm
3   6564700 $1mm-$10mm
于 2013-10-23T13:50:25.417 回答
0

我想您可以将一些计算值连接在一起来动态创建存储桶名称:

select countofsa
      , ((countofsa - 1)/5) * 5 + 1
      , ((countofsa - 1)/5 + 1) * 5 
      , ((countofsa - 1)/5) * 5 + 1 || '-' || ((countofsa - 1)/5 + 1) * 5 AS diff
  from nr_cf_212

一些输出:

 countofsa | ?column? | ?column? | diff
-----------+----------+----------+-------
         1 |        1 |        5 | 1-5
         2 |        1 |        5 | 1-5
         3 |        1 |        5 | 1-5
         4 |        1 |        5 | 1-5
         5 |        1 |        5 | 1-5
         6 |        6 |       10 | 6-10
         7 |        6 |       10 | 6-10
         8 |        6 |       10 | 6-10
         9 |        6 |       10 | 6-10
        10 |        6 |       10 | 6-10
        11 |       11 |       15 | 11-15
(11 rows)

来自注释的更新,Oracle 示例,动态计算范围:

create table nr_cf_212(countofsa number);
insert into nr_cf_212 values(1);
insert into nr_cf_212 values(2);
insert into nr_cf_212 values(3);
insert into nr_cf_212 values(4);
insert into nr_cf_212 values(5);
insert into nr_cf_212 values(6);
insert into nr_cf_212 values(7);
insert into nr_cf_212 values(9);
insert into nr_cf_212 values(10);
insert into nr_cf_212 values(11);

select countofsa
      , TRUNC((countofsa - 1)/5) * 5 + 1
      , (TRUNC((countofsa - 1)/5) + 1) * 5 
      , TRUNC((countofsa - 1)/5) * 5 + 1 || '-' || (TRUNC((countofsa - 1)/5) + 1) * 5 AS diff
  from nr_cf_212;


| COUNTOFSA | TRUNC((COUNTOFSA-1)/5)*5+1 | (TRUNC((COUNTOFSA-1)/5)+1)*5 |  DIFF |
|-----------|----------------------------|------------------------------|-------|
|         1 |                          1 |                            5 |   1-5 |
|         2 |                          1 |                            5 |   1-5 |
|         3 |                          1 |                            5 |   1-5 |
|         4 |                          1 |                            5 |   1-5 |
|         5 |                          1 |                            5 |   1-5 |
|         6 |                          6 |                           10 |  6-10 |
|         7 |                          6 |                           10 |  6-10 |
|         9 |                          6 |                           10 |  6-10 |
|        10 |                          6 |                           10 |  6-10 |
|        11 |                         11 |                           15 | 11-15 |

我用 sqlfiddle ( http://sqlfiddle.com/#!4/b922e/4 ) 试过了。

我把它分成几部分来显示“从”列,“到”列,然后是范围。如果您将数字除以 5 并查看商和余数,您将看到一个模式:

1/5 = 0 remainder 1
2/5 = 0 remainder 2
3/5 = 0 remainder 3
4/5 = 0 remainder 4
5/5 = 1 remainder 0
6/5 = 1 remainder 1
7/5 = 1 remainder 2
8/5 = 1 remainder 3
9/5 = 1 remainder 4
10/5 = 2 remainder 0
11/5 = 2 remainder 1

该数字的范围是“从”5 乘以商“到”5 乘以商加上余数 - 几乎。实际上,一切都被 1 抵消了。所以把你的数字减去 1,然后进行除法。

于 2013-10-23T01:39:38.700 回答