简体   繁体   English

MySQL - 如何连接两个子查询

[英]MySQL - How to join two subqueries

I am trying to create a query that will give me the: - storename - top salesperson - salesperson sales value - manager name 我正在尝试创建一个查询,它将给我: - storename - 顶级销售人员 - 销售人员销售价值 - 经理名称

I have managed to create the two following queries. 我设法创建了以下两个查询。 Both these queries work but I just need help in joining them together. 这两个查询都有效,但我需要帮助将它们连接在一起。

Get top salesperson from each store. 从每家商店获得顶级销售人员。

SELECT MAX(sales) FROM (SELECT shopid, SUM(amount) AS sales 
FROM fss_Payment GROUP BY empnin) AS salesdata GROUP BY shopid

Get All Managers and their store 获取所有经理及其商店

SELECT s.shopname, e.empname FROM fss_Shop s 
JOIN fss_Employee e ON e.shopid = s.shopid AND e.mgrnin="" 
ORDER BY s.shopid

Now I need to join the results of the two queries. 现在我需要加入两个查询的结果。 I tried to do it like below: 我尝试这样做如下:

SELECT * FROM
(SELECT s.shopname, e.empname FROM fss_Shop s 
JOIN fss_Employee e ON e.shopid = s.shopid AND e.mgrnin="" 
) x 
JOIN
(SELECT MAX(sales) FROM (SELECT shopid, SUM(amount) AS sales 
    FROM fss_Payment GROUP BY empnin) AS salesdata GROUP BY shopid
) y 
ON x.shopid = y.shopid

See what some of my tables look like at this link - https://www.db-fiddle.com/f/t94XmTEMgXpmSLS3e8HWAh/1 看看我的一些表格在这个链接上的样子 - https://www.db-fiddle.com/f/t94XmTEMgXpmSLS3e8HWAh/1

UPDATE UPDATE

MySQL 8.0 introduces Window Functions MySQL 8.0引入了窗口函数

https://dev.mysql.com/doc/refman/8.0/en/window-functions.html https://dev.mysql.com/doc/refman/8.0/en/window-functions.html

The original answer below is still applicable to versions of MySQL before 8.0. 以下原始答案仍适用于8.0之前的MySQL版本。


ORIGINAL ANSWER 原始答案

We would think this would be a simple thing to do. 我们认为这将是一件简单的事情。 And some databases give us analytic/windowing functions which makes this fairly easy. 有些数据库为我们提供了分析/窗口函数,这使得它非常简单。 In MySQL, we have a couple of options: go with a straight SQL approach, or make use of some user-defined variables to emulate analytic functions. 在MySQL中,我们有几个选择:采用直接的SQL方法,或者使用一些用户定义的变量来模拟分析函数。

For the straight SQL approach, we can build the query a step at a time. 对于直接SQL方法,我们可以一次构建一个步骤。

First, we can get total sales for each salesperson from each store 首先,我们可以从每个商店获得每个销售人员的总销售额

  SELECT p.shopid
       , p.empnin
       , SUM(p.amount) AS sales
    FROM fss_Payment p
   GROUP
      BY p.shopid
       , p.empnin
   ORDER
      BY p.shopid ASC
       , SUM(p.amount) DESC

Review the results and verify that this is correct. 查看结果并验证这是否正确。 And then we can use that query as an inline view in another query, to get the "highest" total sales for each store: 然后我们可以将该查询用作另一个查询中的内联视图,以获得每个商店的“最高”总销售额:

  -- get highest total sales for each store
  SELECT q.shopid
       , MAX(q.sales) AS highest_sales
    FROM ( SELECT p.shopid
                , p.empnin
                , SUM(p.amount) AS sales
             FROM fss_payment p
            GROUP
               BY p.shopid
                , p.empnin
         ) q
   GROUP
      BY q.shopid
   ORDER
      BY q.shopid

We can take that result, and join it back to the total sales for each salesperson/store, to get the salesperson that had a matching "highest" sales for that store 我们可以获得该结果,并将其加入到每个销售人员/商店的总销售额中,以获得该商店具有匹配的“最高”销售额的销售人员

  -- get salesperson with the highest total sales for each store
  SELECT t.shopid
       , t.empnin
       , t.sales
    FROM ( SELECT q.shopid
                , MAX(q.sales) AS highest_sales
             FROM ( SELECT p.shopid
                         , p.empnin
                         , SUM(p.amount) AS sales
                      FROM fss_payment p
                     GROUP
                        BY p.shopid
                         , p.empnin
                  ) q
            GROUP
               BY q.shopid
         ) r
    JOIN ( SELECT s.shopid
                , s.empnin
                , SUM(s.amount) AS sales
             FROM fss_payment s
            GROUP
               BY s.shopid
                , s.empnin
         ) t
      ON t.shopid = r.shopid
     AND t.sales  = r.highest_sales

If there are two (or more) empnin with the same highest total sales (a tie for first place), this query returns both (or all) of those salesperson. 如果有两个(或更多) empnin具有相同的最高总销售额( empnin第一名),则此查询将返回这两个(或所有)销售人员。

Now we just need to add a join to fss_shop to get the storename , and a couple of joins to fss_employee to get the salesperson name, and to get that saleperson's manager 现在我们只需要添加一个连接到fss_shop来获取storename ,并添加一些连接到fss_employee来获取销售员名称,并获得该销售人员的经理

add this to the query, 将此添加到查询中,

   JOIN fss_shop h 
     ON h.shopid = t.shopid
   LEFT
   JOIN fss_employee e
     ON e.empnin = t.empnin 
   LEFT
   JOIN fss_employee m
     ON m.empnin = e.mgrnin

add an order by clause 添加order by子句

  ORDER BY h.storename, e.empname

and add the appropriate expressions to the SELECT list. 并将适当的表达式添加到SELECT列表中。

Putting that all together, we get something like this: 把它们放在一起,我们得到这样的东西:

  SELECT h.shopname       AS `storename` 
       , e.empname        AS `top salesperson`
       , t.sales          AS `salesperson sales value`
       , m.empname        AS `manager name`
    FROM ( SELECT q.shopid
                , MAX(q.sales) AS highest_sales
             FROM ( SELECT p.shopid
                         , p.empnin
                         , SUM(p.amount) AS sales
                      FROM fss_payment p
                     GROUP
                        BY p.shopid
                         , p.empnin
                  ) q
            GROUP
               BY q.shopid
         ) r
    JOIN ( SELECT s.shopid
                , s.empnin
                , SUM(s.amount) AS sales
             FROM fss_payment s
            GROUP
               BY s.shopid
                , s.empnin
         ) t
      ON t.shopid = r.shopid
     AND t.sales  = r.highest_sales
    JOIN fss_shop h 
      ON h.shopid = t.shopid
    LEFT
    JOIN fss_employee e
      ON e.empnin = t.empnin 
    LEFT
    JOIN fss_employee m
      ON m.empnin = e.mgrnin
   ORDER BY h.storename, e.empname

To answer the question you asked, how to join those two queries together to get the specified result: I don't think it's possible out of those two queries. 要回答你问的问题,如何将这两个查询连接在一起以获得指定的结果:我不认为这两个查询是可能的。


The manager name being returned is the manager of the employee. 返回的manager name是员工的经理。 If we want to get the manager of the shop, change the join criteria for m to match to h instead of e . 如果我们想要获得商店的经理,请更改m的连接条件以匹配h而不是e

The other approach I mentioned is to make use of user-defined variables. 我提到的另一种方法是使用用户定义的变量。 With that approach, it's easier to get just one "top salesperson" per store (when the specification is that there will always be a "tie breaker". There aren't any ties for top salesperson.) 通过这种方法,每个商店更容易获得一个“顶级销售人员”(当规范是总是会有“打破”时。顶级销售人员没有任何联系。)

Using user-defined variables, we might get better performance with large sets. 使用用户定义的变量,我们可以使用大型集合获得更好的性能。 But that approach also relies on behavior that is not guaranteed, as documented in the MySQL Reference Manual. 但是,这种方法还依赖于无法保证的行为,如“MySQL参考手册”中所述。

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

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