我正在尝试创建一个查询,它将给我: - storename - 顶级销售人员 - 销售人员销售价值 - 经理名称
我设法创建了以下两个查询。这两个查询都有效,但我需要帮助将它们连接在一起。
从每家商店获得顶级销售人员。
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
UPDATE
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参考手册”中所述。