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似乎是一个数字,但太晚了,不是吗?也许来杯漂浮着金片的拿铁咖啡?