【问题标题】:MySQL - How to join two subqueriesMySQL - 如何加入两个子查询
【发布时间】:2019-04-27 00:32:44
【问题描述】:

我正在尝试创建一个查询,该查询将为我提供: - 店名 - 顶级销售员 - 销售员销售价值 - 经理姓名

我设法创建了以下两个查询。这两个查询都有效,但我只需要帮助将它们连接在一起。

从每家商店获得顶级销售人员。

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

获取所有经理及其商店

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

现在我需要连接两个查询的结果。我试着这样做:

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

在此链接中查看我的一些表格的外观 - https://www.db-fiddle.com/f/t94XmTEMgXpmSLS3e8HWAh/1

【问题讨论】:

  • 我在第一个关于销售人员的查询中什么也没看到。
  • @GordonLinoff 它从payment 表中获取所有事务的SUM,并将其按empnin 分组,这是员工编号。然后它从每个商店返回MAX
  • 您的小提琴还显示了一个员工被键入到商店,一个员工被键入到一个销售,一个销售被键入到一个商店。混乱的机会。员工可以在她家以外的商店进行销售吗?
  • 您的question from yesterday 发生了什么事?我提供了一个你从未评论过的可能答案。
  • question before that 的答案已得到确认?我还提供了一个您从未评论过的可能答案。

标签: mysql sql


【解决方案1】:

更新

MySQL 8.0 引入窗口函数

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

下面的原始答案仍然适用于 8.0 之前的 MySQL 版本。


原始答案

我们认为这将是一件简单的事情。一些数据库为我们提供了分析/窗口功能,这使得这变得相当容易。在 MySQL 中,我们有两个选择:直接使用 SQL 方法,或者使用一些用户定义的变量来模拟分析函数。

对于直接 SQL 方法,我们可以一次构建查询。

首先,我们可以得到每个商店的每个销售人员的总销售额

  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

查看结果并确认这是正确的。然后我们可以将该查询用作另一个查询中的内联视图,以获得每家商店的“最高”总销售额:

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

我们可以获取该结果,并将其加入到每个销售人员/商店的总销售额中,以获得与该商店匹配的“最高”销售额的销售人员

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

如果有两个(或更多)empnin 具有相同的最高总销售额(并列第一),则此查询将返回所有(或所有)这些销售人员。

现在我们只需要添加一个到fss_shop 的连接来获取storename,以及几个连接到fss_employee 来获取销售人员的姓名,并获取该销售人员的经理

将此添加到查询中,

   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 子句

  ORDER BY h.storename, e.empname

并将适当的表达式添加到 SELECT 列表中。

将所有这些放在一起,我们会得到这样的结果:

  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

要回答您提出的问题,如何将这两个查询连接在一起以获得指定的结果:我认为这两个查询不可能。


返回的manager name 是员工的经理。如果我们想获取商店的经理,请将 m 的加入条件更改为匹配 h 而不是 e

我提到的另一种方法是使用用户定义的变量。使用这种方法,每个商店只获得一名“顶级销售员”会更容易(当规范是总会有一个“决胜局”时。顶级销售员没有任何联系。)

使用用户定义的变量,我们可能会在大集合中获得更好的性能。但该方法也依赖于保证的行为,如 MySQL 参考手册中所述。

【讨论】:

  • 我不太明白你对change the join criteria for m to match to h instead of e. 的意思,这正是我所需要的。你可以编辑答案吗?
猜你喜欢
  • 1970-01-01
  • 2011-06-09
  • 2013-05-18
  • 2014-02-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-07-20
  • 2011-12-23
相关资源
最近更新 更多