【问题标题】:How to use a formula in a SQL query and sort on that result如何在 SQL 查询中使用公式并对该结果进行排序
【发布时间】:2020-11-27 00:40:59
【问题描述】:

在我的公司,我们使用排行榜来展示我们的销售代理的表现。排行榜显示在 HTML 表格中。排行榜现在只包含特定时期(今天、本周和本月)的销售额。现在我想通过添加那些时期的代理商赚取的佣金来扩大排行榜。我使用以下公式计算我公司销售代理期间的佣金:

4*(x/y)*z

其中 x 是代理当月的总销售量,y 是代理当月的总工作时间,z 是代理在特定时期(一天或一周)内的销售量。因此,为了计算某个时期代理的佣金,必须考虑该月剩余时间的表现。

我现在有两个 MySQL 数据表。一种称为销售,另一种称为小时。 Sales 表中的每个条目代表一个销售,其日期为 (finalized_at),当销售完成时,Hours 表中的每个条目代表代理工作的班次,包含工作小时数和班次发生的日期。表格如下所示:

销售表

+-------+--------------+
| agent | finalized_at |
+-------+--------------+
| John  | 01-01-2020   |
+-------+--------------+
| John  | 02-01-2020   |
+-------+--------------+
| Mark  | 01-01-2020   |
+-------+--------------+
| Peter | 04-01-2020   |
+-------+--------------+
| John  | 04-01-2020   |
+-------+--------------+

小时表

+-------+-------+------------+
| agent | hours | date       |
+-------+-------+------------+
| John  | 1     | 01-01-2020 |
+-------+-------+------------+
| John  | 5     | 02-01-2020 |
+-------+-------+------------+
| Mark  | 1     | 01-01-2020 |
+-------+-------+------------+
| Peter | 2     | 04-01-2020 |
+-------+-------+------------+
| John  | 4     | 04-01-2020 |
+-------+-------+------------+

我现在正在尝试运行一个查询,我可以在其中计算从高到低排序的每个代理赚取的佣金。无需创建新的数据表来保存佣金。因此,如果我想计算 1 月 4 日赚取的佣金,我会得到以下结果:

+-------+------------+
| agent | commission |
+-------+------------+
| Peter | 2          |
+-------+------------+
| John  | 1.2        |
+-------+------------+

所以我的问题是:如何构建一个查询,使用两个数据表中的信息来计算特定日期每个代理的佣金。

现在我想出了这个。但这似乎不起作用。如果给我以下错误信息:Reference 'sales' not supported (reference to group function)

SELECT agent,
    COUNT(*) as sales,  
    (4*(SELECT COUNT(*) 
        FROM Sales Sales2 
        WHERE Sales2.agent=Sales.agent AND finalized_at BETWEEN '2020-01-01 00:00:00' AND '2020-01-31 23:59:59'))
        /           
        (SELECT SUM(hours) 
        FROM Hours 
        WHERE date BETWEEN '2020-01-01 00:00:00' AND '2020-01-31 23:59:59' AND agent=Sales.agent) as sph        
FROM Sales 
WHERE finalized_at BETWEEN '2020-01-04 00:00:00' AND '2020-01-04 23:59:59' 
GROUP BY agent 
ORDER by (sph*sales) DESC

【问题讨论】:

  • 能否请您包含您当前的查询?

标签: mysql sql


【解决方案1】:

您可以将查询作为子查询并对结果进行排序,如下所示:

select * from (
  SELECT agent,
    COUNT(*) as sales,  
    (4*(SELECT COUNT(*) 
      FROM Sales Sales2 
      WHERE Sales2.agent=Sales.agent AND finalized_at BETWEEN '2020-01-01 00:00:00' AND '2020-01-31 23:59:59'))
      /           
      (SELECT SUM(hours) 
      FROM Hours 
      WHERE date BETWEEN '2020-01-01 00:00:00' AND '2020-01-31 23:59:59' AND agent=Sales.agent) as sph        
  FROM Sales 
  WHERE finalized_at BETWEEN '2020-01-04 00:00:00' AND '2020-01-04 23:59:59' 
  GROUP BY agent 
) r
order by sales * sph desc;

我不知道你的数据的性质,但我建议你使用独占结束而不是之间,如下:

select * from (
  SELECT agent,
    COUNT(*) as sales,  
    (4*(SELECT COUNT(*) 
      FROM Sales Sales2 
      WHERE Sales2.agent=Sales.agent AND finalized_at >= '2020-01-01' AND finalized_at < '2020-02-01'))
      /           
      (SELECT SUM(hours) 
      FROM Hours 
      WHERE date >= '2020-01-01' AND date < '2020-02-01' AND agent=Sales.agent) as sph        
  FROM Sales 
  WHERE finalized_at >= '2020-01-04' AND finalized_at < '2020-01-05'
  GROUP BY agent 
) r
order by sales * sph desc;

我曾经在“2020-01-04 00:00:00”和“2020-01-04 23:59:59”之间使用,就像你在这里使用的一样,我错过了 1 秒间隔 23:59 的记录:59 到 00:00:00

完整的工作代码在db-fiddle

【讨论】:

  • 关于使用之间的有效点。但我接受风险。这种情况发生的机会非常非常小,即使发生了后果也不会很严重
【解决方案2】:

您可以按计算排序,也可以按计算的别名排序,下面是一个简单的示例,nb 我使用了降序:

CREATE TABLE hours(
   agent  VARCHAR(7)
  ,hours  INTEGER 
  ,date   DATE 
);
INSERT INTO hours(agent,hours,date) VALUES ('John',1,'01-01-2020');
INSERT INTO hours(agent,hours,date) VALUES ('John',5,'02-01-2020');
INSERT INTO hours(agent,hours,date) VALUES ('Mark',1,'01-01-2020');
INSERT INTO hours(agent,hours,date) VALUES ('Peter',2,'04-01-2020');
INSERT INTO hours(agent,hours,date) VALUES ('John',4,'04-01-2020');
select 
      agent
    , sum(hours) as sum_hours
from hours
group by
      agent
order by
   sum(hours) DESC /* repeat the calculation here */
 , agent
代理| sum_hours :---- | --------: 约翰 | 10 彼得 | 2 马克 | 1
select 
      agent
    , sum(hours) as sum_hours
from hours
group by
      agent
order by
   sum_hours DESC /* or use the column alias here */
 , agent
代理| sum_hours :---- | --------: 约翰 | 10 彼得 | 2 马克 | 1

db小提琴 Postgres here

dbfiddle MySQL here

【讨论】:

  • 你们为什么要在 Postgres 中为 MySQL 中的问题提供解决方案?
  • SQL 解决方案不依赖于我在示例中使用的 dbms。在我回答时,db-fiddle 的 MySQL 选项不允许创建示例表。所以我使用了另一个 dbms - 但 SQL 仍然适用于 MySQL
【解决方案3】:

为了计算 x,您可以使用以下查询:

SELECT agent, COUNT(*) AS 'total number of sales in january' 
FROM  Sales
WHERE finilized_at BETWEEEN '01-01-2020' AND '31-01-2020'
GROUP BY 1;

为了计算 y,您可以使用以下查询:

SELECT agent, SUM(hours) 
FROM Hours
WHERE date BETWEEN '01-01-2020' AND '31-01-2020'
GROUP BY 1;

要计算 z(一天),您可以使用以下查询:

SELECT agent, COUNT(*)
FROM Sales
WHERE finalized_at = '01-01-2020'
GROUP BY 1;

您可以使用 ORDER BY 语句对值进行排序。在带有结果的新表中(让它成为佣金),您可以这样使用它:

SELECT * FROM commisions
ORDER BY commission DESC;

【讨论】:

    猜你喜欢
    • 2022-08-21
    • 1970-01-01
    • 2011-09-28
    • 2018-12-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-19
    • 2018-04-12
    相关资源
    最近更新 更多