如何在SQL中执行百分比/总计?

use*_*051 28 sql postgresql

我有一套典型的CUSTOMER/ORDERS表格,我想显示特定客户负责的销售总百分比.我可以像这样获得系统中的订单总数:

SELECT COUNT(order_id) FROM orders
Run Code Online (Sandbox Code Playgroud)

我可以得到客户订单的总数,如下所示:

SELECT COUNT(order_id) FROM orders WHERE cust_id = 541
Run Code Online (Sandbox Code Playgroud)

如何将这些组合成一个返回特定客户销售百分比的查询?谢谢!

hob*_*ave 37

MySQL的:

SELECT ROUND(
  100.0 * (
      SUM(IF(cust_id = 541, 1, 0)) / COUNT(order_id)
  ), 1) AS percent_total
FROM orders;
Run Code Online (Sandbox Code Playgroud)

编辑

我想如果我注意到postgres标签会有所帮助.我认为这是一个MySQL问题.

PostgreSQL的:

SELECT ROUND(
  100.0 * (
      SUM(CASE WHEN cust_id = 541 THEN 1 ELSE 0 END) / COUNT(order_id)
  ), 1) AS percent_total
FROM orders;
Run Code Online (Sandbox Code Playgroud)

PS我的PostgreSQL生锈了,所以如果MySQL查询适用于PostgreSQL我想知道:)

编辑2

我不能强调要警惕下面的计数(*)建议.你通常希望用PostgreSQL来避免这种情况.

  • 至少在PostgreSql中,我认为总和需要在除法之前使用(...):: DECIMAL(5,4)中的东西进行转换,否则除法将是整数除法,结果将为零. (10认同)
  • NoChance是正确的.上面的解决方案对我不起作用(产生0.0),但这样做:`SELECT ROUND(100.0*(SUM(CASE WHEN cust_id = 541 THEN 1 ELSE 0 END):: DECIMAL/COUNT(order_id)),1)AS percent_total FROM orders;` (6认同)
  • 不确定,但也许他意味着postgres每次都会计算数量,这可能是一项昂贵的操作. (3认同)
  • 为什么要在PostgreSQL中避免count(*)? (2认同)
  • 假设orders中的每一行的order_id不为空(这似乎是可能的),那么COUNT(*)与COUNT(order_id)是相同的。COUNT(*)表示“计数输入行数”,而COUNT(foo)表示“计数输入foo不为空的输入行数”。 (2认同)

Rob*_*ott 10

一种解决方案是使用嵌套查询 -

SELECT count(*) / (SELECT count(*) FROM orders)
FROM orders
WHERE cust_id = 541
Run Code Online (Sandbox Code Playgroud)

  • 我还想补充一句:"更容易打字"必须成为做某事的最糟糕理由之一.除非你在某种竞争中尽可能在尽可能短的时间内完成尽可能多的代码. (3认同)
  • 一个更简单的方法是通过cust_id从订单组中选择cust_id,(count(*)/(从订单中选择count(1))*100); (3认同)
  • 不,这是一件非常糟糕的事情.在PostgreSQL中,count(*)不是像MySQL那样的O(1).此查询需要两次全表扫描.这是不必要的,并且随着桌子尺寸的增加而变得非常糟糕. (2认同)