如何处理 Snowflake 中的动态舍入 SQL
How to handle Dynamic Rounding in Snowflake SQL
我正在尝试使用 ROUND 函数处理 Snowflake 中的动态舍入。
我有两个table,一个是BUCKET_TABLE,结构如下
COUNTRY
BUCKET1
BUCKET2
US
1
2
CANADA
100
200
其他table是PRODUCT_SIZES
COUNTRY
PRODUCT_SIZE
US
1.5
CANADA
150
最后我需要创建一个 table - 预期结果 Table
COUNTRY
PRODUCT_SIZE
SIZE_RANGE
US
1.5
1-1.99
CANADA
150
100-199
我得到的是这样的。
COUNTRY
PRODUCT_SIZE
SIZE_RANGE
US
1.5
1-1.99
CANADA
150
100-199.00
这是我正在使用的查询。
SELECT
COUNTRY,
CASE WHEN LENGTH(PRODUCT_SIZE)>2 THEN 1 ELSE 0.01 END AS SIZE_RANGE_ALLOCATOR,
CASE WHEN LENGTH(PRODUCT_SIZE)>2 THEN 0 ELSE 2 END AS SIZE_RANGE_ROUNDER,
CASE when PRODUCT_SIZE >= BCKT.bucket1 and PRODUCT_SIZE < BCKT.bucket2
then concat(BCKT.bucket1,'-',round(BCKT.bucket2-SIZE_RANGE_ALLOCATOR,SIZE_RANGE_ROUNDER))
END AS SIZE_RANGE
from PRODUCT_SIZES pz
inner join BUCKET_TABLE BCKT
on pz.country = bckt.country
当我在 round 函数中硬编码 0 时,我得到的是加拿大的预期结果,但美国的结果是错误的。
round(BCKT.bucket2-SIZE_RANGE_ALLOCATOR,0)
是否有另一种方法可以在 Snowflake 中动态处理舍入 SQL?
LENGTH(PRODUCT_SIZE)
3
5
都“长于 2”
感觉像:
PRODUCT_SIZE >= 100 THEN 1 ELSE 0.01
逻辑会更好,但如果你使用 >3 它会如你所愿:
WITH BUCKET_TABLE as (
SELECT * FROM VALUES
('US' ,1 ,2),
('CANADA' ,100 ,200)
t(COUNTRY, BUCKET1, BUCKET2)
), PRODUCT_SIZES as (
SELECT * FROM VALUES
('US' ,1.5),
('CANADA' ,150)
t(COUNTRY, PRODUCT_SIZE)
)
SELECT
pz.COUNTRY,
PRODUCT_SIZE,
LENGTH(PRODUCT_SIZE),
CASE WHEN LENGTH(PRODUCT_SIZE)>3 THEN 1 ELSE 0.01 END AS SIZE_RANGE_ALLOCATOR,
CASE WHEN LENGTH(PRODUCT_SIZE)>3 THEN 0 ELSE 2 END AS SIZE_RANGE_ROUNDER,
CASE when PRODUCT_SIZE >= BCKT.bucket1 and PRODUCT_SIZE < BCKT.bucket2
then concat(BCKT.bucket1,'-', IFF(LENGTH(PRODUCT_SIZE)>3, round(BCKT.bucket2 - SIZE_RANGE_ALLOCATOR,0)::text, round(BCKT.bucket2 - SIZE_RANGE_ALLOCATOR,2)::text) )
END AS SIZE_RANGE2
from PRODUCT_SIZES pz
inner join BUCKET_TABLE BCKT
on pz.country = bckt.country
COUNTRY
PRODUCT_SIZE
LENGTH(PRODUCT_SIZE)
SIZE_RANGE_ALLOCATOR
SIZE_RANGE_ROUNDER
SIZE_RANGE2
US
1.5
3
0.01
2
1-1.99
CANADA
150
5
1
0
100-199
我正在尝试使用 ROUND 函数处理 Snowflake 中的动态舍入。
我有两个table,一个是BUCKET_TABLE,结构如下
COUNTRY | BUCKET1 | BUCKET2 |
---|---|---|
US | 1 | 2 |
CANADA | 100 | 200 |
其他table是PRODUCT_SIZES
COUNTRY | PRODUCT_SIZE |
---|---|
US | 1.5 |
CANADA | 150 |
最后我需要创建一个 table - 预期结果 Table
COUNTRY | PRODUCT_SIZE | SIZE_RANGE |
---|---|---|
US | 1.5 | 1-1.99 |
CANADA | 150 | 100-199 |
我得到的是这样的。
COUNTRY | PRODUCT_SIZE | SIZE_RANGE |
---|---|---|
US | 1.5 | 1-1.99 |
CANADA | 150 | 100-199.00 |
这是我正在使用的查询。
SELECT
COUNTRY,
CASE WHEN LENGTH(PRODUCT_SIZE)>2 THEN 1 ELSE 0.01 END AS SIZE_RANGE_ALLOCATOR,
CASE WHEN LENGTH(PRODUCT_SIZE)>2 THEN 0 ELSE 2 END AS SIZE_RANGE_ROUNDER,
CASE when PRODUCT_SIZE >= BCKT.bucket1 and PRODUCT_SIZE < BCKT.bucket2
then concat(BCKT.bucket1,'-',round(BCKT.bucket2-SIZE_RANGE_ALLOCATOR,SIZE_RANGE_ROUNDER))
END AS SIZE_RANGE
from PRODUCT_SIZES pz
inner join BUCKET_TABLE BCKT
on pz.country = bckt.country
当我在 round 函数中硬编码 0 时,我得到的是加拿大的预期结果,但美国的结果是错误的。
round(BCKT.bucket2-SIZE_RANGE_ALLOCATOR,0)
是否有另一种方法可以在 Snowflake 中动态处理舍入 SQL?
LENGTH(PRODUCT_SIZE) |
---|
3 |
5 |
都“长于 2”
感觉像:
PRODUCT_SIZE >= 100 THEN 1 ELSE 0.01
逻辑会更好,但如果你使用 >3 它会如你所愿:
WITH BUCKET_TABLE as (
SELECT * FROM VALUES
('US' ,1 ,2),
('CANADA' ,100 ,200)
t(COUNTRY, BUCKET1, BUCKET2)
), PRODUCT_SIZES as (
SELECT * FROM VALUES
('US' ,1.5),
('CANADA' ,150)
t(COUNTRY, PRODUCT_SIZE)
)
SELECT
pz.COUNTRY,
PRODUCT_SIZE,
LENGTH(PRODUCT_SIZE),
CASE WHEN LENGTH(PRODUCT_SIZE)>3 THEN 1 ELSE 0.01 END AS SIZE_RANGE_ALLOCATOR,
CASE WHEN LENGTH(PRODUCT_SIZE)>3 THEN 0 ELSE 2 END AS SIZE_RANGE_ROUNDER,
CASE when PRODUCT_SIZE >= BCKT.bucket1 and PRODUCT_SIZE < BCKT.bucket2
then concat(BCKT.bucket1,'-', IFF(LENGTH(PRODUCT_SIZE)>3, round(BCKT.bucket2 - SIZE_RANGE_ALLOCATOR,0)::text, round(BCKT.bucket2 - SIZE_RANGE_ALLOCATOR,2)::text) )
END AS SIZE_RANGE2
from PRODUCT_SIZES pz
inner join BUCKET_TABLE BCKT
on pz.country = bckt.country
COUNTRY | PRODUCT_SIZE | LENGTH(PRODUCT_SIZE) | SIZE_RANGE_ALLOCATOR | SIZE_RANGE_ROUNDER | SIZE_RANGE2 |
---|---|---|---|---|---|
US | 1.5 | 3 | 0.01 | 2 | 1-1.99 |
CANADA | 150 | 5 | 1 | 0 | 100-199 |