CASE WHEN 从列创建 bin 的替代方案
Alternative to CASE WHEN to create bins from a column
我有一个 table,其中一列 (COL1
) 的值可以从 0 到 1(含)。从这个专栏我想创建一个新的列来分类 COL1
使用预定义的范围(即创建容器)。当类别/箱数较少时,可以使用 CASE WHEN
轻松完成,例如:
SELECT
CASE WHEN COL1 <= 0.2 THEN 1
WHEN COL1 > 0.2 AND COL1 <= 0.4 THEN 2
....
WHEN COL1 > 0.8 AND COL1 <= 1 THEN 5
END AS COL1_bin
FROM Table
因为我想要 100 个 bin,所以我正在寻找一种方法来 'automatically' 使用一个函数,例如,我可以在其中给出最小值、最大值和步长/binsize(例如,最小值 = 0,最大值 = 1,步长 = 0.01)
我在 HiveQL 中这样做,应该与 MySQL 非常相似。
这是一种方法。如果假设您希望 bin 范围为 0.1,0.2,0.3,... 直到 1。那么您将使用块 row_gen 生成 10 行并将 step_size 设置为 row_number/10 ,并通过为每个 bin 设置 lower_limit 和 upper_limit。
之后,您需要检查 col1 的值是否符合 bin 的相应下限和上限,如下所示。 (我使用 left join 来包含 col1 值为 null 的情况。如果这不是一种可能的情况,则可以将其更改为常规 join)
with row_gen
as (select top 10
,row_number() over(order by 1) as bin_id
,row_number() over(order by 1)/10 as as lower_limit
,row_number() over(order by 1)/10 + 1/10 as as upper_limit
from table /*any table that has 10 rows*/
)
select a.*
,b.bin_id
from your_table a
left join row_gen b
on a.col1 between b.lower_rnk and b.upper_rnk
我不确定 Hive 是否有装箱功能(Postgres 有)。但是你可以使用算术:
select floor( greatest(least($maxval, col1), $minval) - $minval) /
$step_size
) as bin
from t;
如果您想要数据中的最小值和最大值,可以使用 window 函数:
select floor( greatest(least(maxval, col1), minval) - minval) /
$step_size
) as bin
from (select t.*,
min(col1) over () as minval,
max(col1) over () as maxval
from t
) t;
严格来说,计算不需要子查询。但这允许 bin
用于聚合。
我有一个 table,其中一列 (COL1
) 的值可以从 0 到 1(含)。从这个专栏我想创建一个新的列来分类 COL1
使用预定义的范围(即创建容器)。当类别/箱数较少时,可以使用 CASE WHEN
轻松完成,例如:
SELECT
CASE WHEN COL1 <= 0.2 THEN 1
WHEN COL1 > 0.2 AND COL1 <= 0.4 THEN 2
....
WHEN COL1 > 0.8 AND COL1 <= 1 THEN 5
END AS COL1_bin
FROM Table
因为我想要 100 个 bin,所以我正在寻找一种方法来 'automatically' 使用一个函数,例如,我可以在其中给出最小值、最大值和步长/binsize(例如,最小值 = 0,最大值 = 1,步长 = 0.01)
我在 HiveQL 中这样做,应该与 MySQL 非常相似。
这是一种方法。如果假设您希望 bin 范围为 0.1,0.2,0.3,... 直到 1。那么您将使用块 row_gen 生成 10 行并将 step_size 设置为 row_number/10 ,并通过为每个 bin 设置 lower_limit 和 upper_limit。
之后,您需要检查 col1 的值是否符合 bin 的相应下限和上限,如下所示。 (我使用 left join 来包含 col1 值为 null 的情况。如果这不是一种可能的情况,则可以将其更改为常规 join)
with row_gen
as (select top 10
,row_number() over(order by 1) as bin_id
,row_number() over(order by 1)/10 as as lower_limit
,row_number() over(order by 1)/10 + 1/10 as as upper_limit
from table /*any table that has 10 rows*/
)
select a.*
,b.bin_id
from your_table a
left join row_gen b
on a.col1 between b.lower_rnk and b.upper_rnk
我不确定 Hive 是否有装箱功能(Postgres 有)。但是你可以使用算术:
select floor( greatest(least($maxval, col1), $minval) - $minval) /
$step_size
) as bin
from t;
如果您想要数据中的最小值和最大值,可以使用 window 函数:
select floor( greatest(least(maxval, col1), minval) - minval) /
$step_size
) as bin
from (select t.*,
min(col1) over () as minval,
max(col1) over () as maxval
from t
) t;
严格来说,计算不需要子查询。但这允许 bin
用于聚合。