【问题标题】:How to calculate how many times a number goes into another number in SQL?如何计算一个数字在 SQL 中进入另一个数字的次数?
【发布时间】:2021-07-20 15:01:21
【问题描述】:

试图找出解决此问题的最佳方法。为了简单起见,我将编造一些不合理的情况作为例子;我是一个商人,有一些垃圾数据,我不知道人们购买的物品数量,所以我必须回到它

  • 我有三种产品,客户以三种不同的价格购买了(250 美元、350 美元、500 美元)
  • 我有客户支付的总金额(与本示例无关的税款/退款等)

因此,如果我知道一位客户支付了 600 美元 - 他们很可能以 250 美元的价格购买了一种产品,以 350 美元的价格购买了一种产品。如果客户支付了 1000 美元,那么他们要么以 500 美元的价格购买了 2 件产品,要么以 250 美元的价格购买了 4 件产品,或者以 250 美元*2 和 500 美元的价格购买了 3 件产品(谢谢@dennis)。

我想要的是这样的:

customer_id total_amount_paid assumed_number_of_products assumed_prices
1241 1000 4 250, 250, 250, 250
1241 1000 2 500, 500
1241 1000 3 250, 250, 500
0912 600 2 250, 350

任何建议都会有所帮助。真的一直在尝试解决这个问题而不想太多。

【问题讨论】:

  • 有趣的挑战。我会考虑更多,但要指出的是 250 美元 + 350 美元不是 700 美元。 :)。同样用 1000 美元,可能有 2*250 + 1*500。 700,他们得到 2*350
  • 哎呀,我的脑子坏了。感谢您发现 - 已编辑!
  • 所以你的表只有两列 customer_idtotal_amount_paid ?您想知道有多少组合并使用 SQL 查询列出您给定 total_amount_paid 的所有组合,对吗?
  • 虽然随着产品数量的增加,这会导致很多排列和组合,但最懒惰/最贪婪的解决方案是假设客户总是选择最昂贵的产品,然后使用更便宜的产品解决变化?
  • @LukaszSzozda 很有趣!就这样我在同一页上,你建议倒退吗?即计算 500 / 250 / 350 组合的所有可能值,然后将其与原始表与支付的总金额相匹配?

标签: sql snowflake-cloud-data-platform snowflake-sql


【解决方案1】:

很酷的问题...

Snowflake 的好处是我们可以使用蛮力方法...预先计算所有可能的组合,然后使用 qualifyrow_number 过滤重复项,并使用 ascii

为了让它更有趣,我加入了退货(因此数量可以从 -10 到 10)并添加了第四个产品 @ 135 美元。我确实将不同产品的总数限制为 2 个……但这可以轻松地推到 3 个。

select 
    cust_total,
    product, 
    second_product,
    quantity,
    second_quantity,
    ascii(product)+ascii(second_product) basket,
    quantity+second_quantity basket_quantity 
from     
    (select
    ap1.product,
    ap2.product second_product,
    ap1.quantity,
    ap2.quantity second_quantity,
    sum(ap1.revenue_combos) + sum(ap2.revenue_combos) cust_total
from
    all_possibles ap1,
    all_possibles ap2
where
    ap1.product<>ap2.product
group by
    1,2,3,4)
group by 
    1,2,3,4,5,6  
qualify
    1=  
    row_number() over 
        (partition by cust_total,basket,basket_quantity 
         order by     product,second_product)

完整复制|粘贴|在 SQL 中运行:

with all_possibles as (
select
    *
from
    (
        SELECT
            seq4() -10 quantity,
            quantity * prod_price_1 A,
            quantity * prod_price_2 B,
            quantity * prod_price_3 C,
            quantity * prod_price_4 D
        FROM
            TABLE (GENERATOR (ROWCOUNT => 21)),
            (
                select
                   /*UNIFORM (1, 500, random())*/250::int prod_price_1,
                   /*UNIFORM (1, 500, random())*/350::int prod_price_2,
                   /*UNIFORM (1, 500, random())*/500::int prod_price_3,
                   /*UNIFORM (1, 500, random())*/135::int prod_price_4
            )
    ) unpivot (
        revenue_combos for product in (
            A,
            B,
            C,
            D
        )
    )
 )

 select 
cust_total,
product, 
second_product,
quantity,
second_quantity,
ascii(product)+ascii(second_product) basket,
quantity+second_quantity basket_quantity 
 from     
 (select
ap1.product,
ap2.product second_product,
ap1.quantity,
ap2.quantity second_quantity,
sum(ap1.revenue_combos) + sum(ap2.revenue_combos) cust_total
 from
all_possibles ap1,
all_possibles ap2
 where
ap1.product<>ap2.product
 group by
1,2,3,4)
 group by 1,2,3,4,5,6  
 qualify
1=  row_number() over (partition by cust_total,basket,basket_quantity order by product,second_product )

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-09-20
    • 1970-01-01
    • 2015-01-28
    • 1970-01-01
    • 2014-11-14
    • 2010-11-11
    • 2021-09-12
    • 1970-01-01
    相关资源
    最近更新 更多