简体   繁体   English

如何在 SQL 查询中使用公式并对该结果进行排序

[英]How to use a formula in a SQL query and sort on that result

In my company we use a leaderboard to show the performance of our sales agents.在我的公司,我们使用排行榜来显示我们的销售代理的表现。 The leadersboard is shown in an HTML table.排行榜显示在 HTML 表中。 The leaderboard now only contains the amount of sales made of certain periods (today, this week and this month).排行榜现在只包含特定时期(今天、本周和本月)的销售额。 Now I want to expand the leaderboard by adding the earned commissions by the agents of those periods.现在我想通过添加那些时期的代理商赚取的佣金来扩大排行榜。 I use the following formula to calculate the commissions of a periode of sales agents in my company:我使用以下公式计算我公司销售代理期间的佣金:

4*(x/y)*z

Where x is the total number of sales an agent made that month, y is the total hours an agent worked that month and z is the number of sales an agent made in a certain period (a day or a week).其中 x 是代理当月的总销售额,y 是代理当月的总工作时间,z 是代理在特定时期(一天或一周)内的销售额。 Thus in order to calculate the commission of an agent of a certain periode the performance of the rest of the month has to be taken in account.因此,为了计算某个时期的代理商佣金,必须考虑当月 rest 的性能。

I now have two MySQL data tables.我现在有两个 MySQL 数据表。 One is called Sales and the other one is called Hours.一种称为销售,另一种称为小时。 Each entry in the Sales table represents one sale with the date (finalized_at) when the sale has been made and each entry in the Hours table represents a shift worked by the agent containing the hours worked and the date when the shift has taken place. Sales 表中的每个条目都代表一个销售,其日期为 (finalized_at),当销售完成时,Hours 表中的每个条目代表代理工作的班次,包含工作时间和班次发生的日期。 The tables look like this:表格如下所示:

Sales table销售表

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

Hours table小时表

+-------+-------+------------+
| 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 |
+-------+-------+------------+

I am now trying to run a query where I can calculate the earned commissions per agent sorted from high to low.我现在正在尝试运行一个查询,我可以在其中计算从高到低排序的每个代理赚取的佣金。 Without creating a new data table to save the commissions.无需创建新的数据表来保存佣金。 So if I would for example wanted to calculate the commissions earned on january 4th, I would have gotten the following result:因此,如果我想计算 1 月 4 日赚取的佣金,我会得到以下结果:

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

So my question is: How can I structure one query where I use information from both data tables to calculate the commission per agent on a certain date.所以我的问题是:如何构建一个查询,使用两个数据表中的信息来计算特定日期每个代理的佣金。

For now I came up with this.现在我想出了这个。 But this doesn't seem to work.但这似乎不起作用。 If gives me the following error message: Reference 'sales' not supported (reference to group function)如果给我以下错误消息: 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

You can put the query as sub query and sort the result, like this:您可以将查询作为子查询并对结果进行排序,如下所示:

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;

I do not know the nature of your data, but I would suggest you to use exclusive end instead of between, as follows:我不知道你的数据的性质,但我建议你使用独占端而不是之间,如下:

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;

I once used between like the one you employed here BETWEEN '2020-01-04 00:00:00' AND '2020-01-04 23:59:59' and I missed records for 1 second interval 23:59:59 to 00:00:00我曾经在“2020-01-04 00:00:00”和“2020-01-04 23:59:59”之间使用,就像你在这里使用的那样,我错过了 1 秒间隔 23:59:59 到00:00:00

The complete working code at db-fiddle db-fiddle的完整工作代码

You can order by the calculation, or by the alias you give to that calculation, a simple example of this is below, nb I have used descending order:您可以按计算排序,也可以按您为该计算提供的别名排序,下面是一个简单的示例,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
 agent |代理| sum_hours:---- | sum_hours:---- | --------: John | --------: 约翰 | 10 Peter | 10 彼得 | 2 Mark | 2 马克 | 1 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
 agent |代理| sum_hours:---- | sum_hours:---- | --------: John | --------: 约翰 | 10 Peter | 10 彼得 | 2 Mark | 2 马克 | 1 1

db<>fiddle Postgres here db<>fiddle Postgres 在这里

db<>fiddle MySQL here db<>fiddle MySQL 在这里

In order to count x you can use this query:为了计算 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;

In order to calculate y you can use this query:为了计算 y 你可以使用这个查询:

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

And to calculate z(a day) you can use this query:要计算 z(a day),您可以使用以下查询:

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

You can use ORDER BY statement to sort values.您可以使用 ORDER BY 语句对值进行排序。 In the new table with results(let it be commissions) you would use it like this:在带有结果的新表中(让它成为佣金),您可以像这样使用它:

SELECT * FROM commisions
ORDER BY commission DESC;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM