Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/63.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/78.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Mysql 基于红移或排名分配特定值_Mysql_Sql_Postgresql_Amazon Redshift - Fatal编程技术网

Mysql 基于红移或排名分配特定值

Mysql 基于红移或排名分配特定值,mysql,sql,postgresql,amazon-redshift,Mysql,Sql,Postgresql,Amazon Redshift,我有一张桌子,如图所示。该表有5列, 交易的时间, 客户识别码, 订单号:, 订单价值和 符合条件的折扣 合格的折扣仅为订单价值的10%。 现在我想根据客户的交易时间给他们打折扣,但折扣是 每个客户最多20美元。数据中的适用折扣是我要计算的列。 我使用以下代码根据客户id和交易时间对数据进行排序,但我不知道如何计算适用的折扣列。需要帮助为红移生成查询 +---------------------+-------------+------------+-------------+---------

我有一张桌子,如图所示。该表有5列, 交易的时间, 客户识别码, 订单号:, 订单价值和 符合条件的折扣

合格的折扣仅为订单价值的10%。 现在我想根据客户的交易时间给他们打折扣,但折扣是 每个客户最多20美元。数据中的适用折扣是我要计算的列。 我使用以下代码根据客户id和交易时间对数据进行排序,但我不知道如何计算适用的折扣列。需要帮助为红移生成查询

+---------------------+-------------+------------+-------------+-------------------+---------------------+
| Time_of_transaction | Customer_id |  Order_id  | Order_Value | Eligible_discount | Applicable_Discount |
+---------------------+-------------+------------+-------------+-------------------+---------------------+
| 11/1/2019 12:34     |        1234 | 8682686399 |         100 | 10                | 10                  |
| 11/2/2019 12:14     |        1234 |  144141455 |          20 | 2                 | 2                   |
| 11/5/2019 22:14     |        1234 | 1424535235 |          45 | 4.5               | 4.5                 |
| 11/7/2019 9:14      |        1234 |  463637675 |          65 | 6.5               | 3.5                 |
| 11/7/2019 10:20     |        1234 |   12242144 |          30 | 3                 | 0                   |
| 11/7/2019 18:10     |        1234 |  141351555 |          80 | 8                 | 0                   |
| 12/1/2019 12:34     |        5678 |  124421552 |         230 | 23                | 20                  |
| 12/2/2019 12:14     |        5678 |  357757757 |         130 | 13                | 0                   |
| 12/5/2019 22:14     |        5678 |   28668890 |          80 | 8                 | 0                   |
| 12/7/2019 9:14      |        5678 |   68568889 |         120 | 12                | 0                   |
| 12/7/2019 10:20     |        5678 |  314124455 |          45 | 4.5               | 0                   |
+---------------------+-------------+------------+-------------+-------------------+---------------------+
订单级别的20美元上限 计算您的适用折扣应该是
最小值(订单价值*0.1,20)
,即您的订单价值*10%上限为20

   select Time_of_transaction, Customer_id, Order_id,Order_Value, 
0.1*Order_Value as Eligible_discount,
row_number() over 
(partition by Customer_id
 order by Time_of_transaction asc) as row
from cust_tran_info
order by 2,1
见演示

20美元上限适用于用户级别 如果对另一个答案的评论表明,您希望在用户级别而不是订单级别累积施加20美元的上限,那么您应该使用此选项:

select  Time_of_transaction,
        Customer_id,
        Order_id,
        Order_Value, 
        least(Order_Value * 0.1, 20) as Applicable_Discount,
        row_number() over (partition by Customer_id order by Time_of_transaction asc) as row
from    cust_tran_info
order by 2,1
见演示。一开始这看起来可能有点混乱,但基本上是计算所有以前订单(不包括当前订单)的折扣总额,以确定当前订单的20美元上限(如果有的话)还有多少剩余

完整sql:

least(Order_Value * 0.1, greatest(0, 20 - coalesce(sum(Order_Value) over(partition by Customer_id order by Time_of_transaction asc ROWS between UNBOUNDED PRECEDING and 1 PRECEDING) * 0.1, 0)))

您可以在子查询中使用窗口和,在外部查询中使用算术逻辑,如下所示:

select  Time_of_transaction,
        Customer_id,
        Order_id,
        Order_Value,
        row_number() over (partition by Customer_id order by Time_of_transaction asc) Customer_Order_Sequence,
        least(Order_Value * 0.1, greatest(0, 20 - coalesce(sum(Order_Value) over(partition by Customer_id order by Time_of_transaction asc ROWS between UNBOUNDED PRECEDING and 1 PRECEDING) * 0.1, 0))) discount_to_be_given_on_current_order     
from    cust_tran_info
order by 2,1

mysql还是postgresql?这似乎是你最不想要的
LEAST(0.1*stuff,20)
,再说一次,我忍不住觉得这些检查很有用unnecessary@Strawberry:据我所知,OP希望每位客户的累计折扣总额不超过20,因此
least()
在这里似乎不是一个选项。您可能是对的,但至少在那个时刻仍然可以使用min。这不是min的工作方式。请在发布之前测试代码。@谢谢您的评论,我们已经解决了这个问题。我的意思是输入LEAST而不是MIN。现在在上面的链接中也进行了测试。@仅供参考,我再次更新了我的答案,以包含一个解决方案,以防该人员希望在用户级别而不是订单级别设置上限。我无法对另一个答案发表评论:/
select 
    t.*,
    case 
        when coalesce(sum_discount, 0) > 20 then 0
        when sum_discount + order_value * 0.1 > 20 then 20 - sum_discount
        else order_value * 0.1
    end applicable_discount
from (
    select 
        t.*,
        sum(order_value * 0.1) over(
            partition by customer_id 
            order by time_of_transaction
            rows between unboundeed preceding and 1 preceding
        ) sum_discount
    from mytable t
) t