Mysql SQL:如何找到支付80%收入的顶级客户?

Mysql SQL:如何找到支付80%收入的顶级客户?,mysql,sql,mariadb,subtotal,Mysql,Sql,Mariadb,Subtotal,假设我有一个表事务: desc customer_transactions; +------------------------------+--------------+------+-----+---------+----------------+ | Field | Type | Null | Key | Default | Extra | +------------------------------+--

假设我有一个表事务:

desc customer_transactions; 
+------------------------------+--------------+------+-----+---------+----------------+
| Field                        | Type         | Null | Key | Default | Extra          |
+------------------------------+--------------+------+-----+---------+----------------+
| id                           | int(11)      | NO   | PRI | NULL    | auto_increment |
| transactionID                | varchar(128) | YES  |     | NULL    |                |
| customerID                   | varchar(128) | YES  |     | NULL    |                |
| amountAuthorized             | DECIMAL(5,2) | YES  |     | NULL    |                |
| createdDatetime              | datetime     | YES  |     | NULL    |                |
+------------------------------+--------------+------+-----+---------+----------------+
此表记录了过去5年SAAS业务的信用卡交易。该业务有一个典型的每月订阅模式,客户根据他们的计划自动收费

我需要找到在每个时间段内占全部收入80%的顶级客户。SAAS业务非常不平衡,因为一些客户每月支付10美元,其他客户可能每月支付数千美元

稍后我将添加一个时间段过滤器,只是需要聚合方面的帮助

我想生成一份报告,其中我只选择以这种格式产生80%收入的客户:

+------------+-------+
| customerID | Total | 
+------------+-------+
不知道为什么这个问题被搁置。我只是需要帮助编写查询,但没有足够的SQL经验。基本上,问题的标题说明了这里需要什么:

我需要列出客户及其相应的总数,但是,只需要选择占总收入80%的客户。报告需要汇总每个客户的总数

使用MariaDB版本10.3.9时,请使用以下命令:

SELECT 
  ct1.customerID, 
  SUM(ct1.amountAuthorized) as Total, 
  100 * (SUM(ct1.amountAuthorized) / ct3.total_revenue) as percent_revenue 
FROM 
  customer_transactions ct1
CROSS JOIN (SELECT SUM(amountAuthorized) AS total_revenue 
            FROM customer_transactions ct2) AS ct3 
GROUP BY 
  ct1.customerID 
HAVING percent_revenue >= 80

这是您需要使用窗口函数来实现的类型

WITH 
    -- define some sample data, 
    -- where the sum total of amountAuthorized is 10,000
    customer_transactions(  `id`, transactionID, customerID, 
                            amountAuthorized, createdDatetime) AS
    (
                    SELECT 1, 1, 1, 5000, '2018-08-01'
        UNION ALL   SELECT 2, 2, 2, 2000, '2018-08-01'
        UNION ALL   SELECT 3, 3, 3, 1000, '2018-08-01'
        UNION ALL   SELECT 4, 4, 4, 1000, '2018-08-01'
        UNION ALL   SELECT 5, 5, 5, 1000, '2018-08-01'
    )
    -- a query that gives us the running total, sorted to give us the biggest customers first.
    -- note that the additional sorts affect what customers might be returned.
    ,running_totals AS
    (
        SELECT *, SUM(amountAuthorized) OVER (ORDER BY amountAuthorized DESC, createdDatetime DESC, `id`)  AS runningTotal
        FROM customer_transactions
    )
SELECT *
FROM running_totals
WHERE runningTotal <= ( SELECT 0.8 * SUM(amountAuthorized) 
                        FROM customer_transactions)

注意,这不考虑表中所有数据的双关语。当您只想查看特定的时间段时,您可能需要创建一个中间CTE来过滤掉您想要的日期。

您会发现,令人惊讶的是,近20%的客户占80%。看

但是,如果你不想朝这个方向走,你有两个选择:

切换到MySQL 8.0或MariaDB 10.1以使用“窗口”功能;或 使用@variables生成运行总数,然后在外部查询中获取所需的行。 因为您使用的是MariaDB 10.3.9,所以窗口似乎是一种方式。但首先,您需要一个单独的查询或派生表来计算总收入,这样您就可以得到其中的80%

暗示

 SELECT @revenue80 := 0.8 * SUM(amountAuthorized) 
     FROM customer_transactions
然后在Zack建议的地方使用@revenue80


我知道每个金额不能超过999.99。真正地这是咖啡店吗?

如何使用这些数据计算收入的百分比?除了id,我在表上没有看到任何数字类型。还有80%的收入?总收入的80%?根据定义,这只能是0或1个客户,因为如果有一个客户产生了80%或以上的收入,则任何其他客户产生的收入都会少于总收入的20%。计算客户收入的逻辑是什么?编辑问题,添加有关当前问题的更多信息,即您遇到的问题,向我们展示您当前的尝试。另外,您使用的数据库管理系统是mysql、sql server、oracle、db2、postgres等等?为什么数量是varchar!未授权的定义为VARCHAR128。如何对字符串进行求和和和除法?此外,即使列是数字,您的逻辑也是错误的。只有当一个客户的收入超过80%时,这才是正确的。我只是无法想象OP真的在寻找一个能够自己创造80%收入的客户。只有一个客户返回,或者没有客户返回,这将是一个愚蠢的查询。@KenWhite添加了将varchar转换为Double的Cast,对不起,伙计们。我将金额改为十进制。@ipolevoy您在我的答案中运行了查询吗?它应该能正常工作。谢谢你的建议,我不熟悉窗口的功能。999.99的数字是巧合。这是针对SaaS业务的,它可以有更大的事务。此外,999.99似乎是一个数字,但太晚了,不是吗?也许来杯漂浮着金片的拿铁咖啡?