I am trying to handle the dynamic rounding in Snowflake using ROUND Function.
I have two tables, one is BUCKET_TABLE with below structure
COUNTRY | BUCKET1 | BUCKET2 |
---|---|---|
US | 1 | 2 |
CANADA | 100 | 200 |
Other table is PRODUCT_SIZES
COUNTRY | PRODUCT_SIZE |
---|---|
US | 1.5 |
CANADA | 150 |
Lastly I need to create a below table - Expected Result Table
COUNTRY | PRODUCT_SIZE | SIZE_RANGE |
---|---|---|
US | 1.5 | 1-1.99 |
CANADA | 150 | 100-199 |
What I am getting is this way.
COUNTRY | PRODUCT_SIZE | SIZE_RANGE |
---|---|---|
US | 1.5 | 1-1.99 |
CANADA | 150 | 100-199.00 |
Here is the query I am using.
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
When I am hardcoding 0 in round function then I am getting expected results for Canada but gets wrong results for US.
round(BCKT.bucket2-SIZE_RANGE_ALLOCATOR,0)
Is there another way to handle the rounding Dynamically in Snowflake SQL ?
CodePudding user response:
LENGTH(PRODUCT_SIZE) |
---|
3 |
5 |
both are "longer than 2"
feels like:
PRODUCT_SIZE >= 100 THEN 1 ELSE 0.01
would be better logic, but if you use >3 it works as you want:
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 |