MySQL - 如何限制每个ID的一个结果?

时间:2017-11-28 14:06:33

标签: mysql sql

我有以下查询创建一个视图表,显示商店中最高的销售人员,其他细节很少:

CREATE OR REPLACE VIEW sales_data AS 
SELECT s.storename AS "Store", 
       e.employee_name AS "Employee", 
       e1.employee_name AS "Manager", 
       SUM(p.total_sale_value) AS "Sales Value" 
FROM fss_Shop s 
       JOIN Employee e ON e.storeid = s.storeid 
       JOIN Payment p ON p.employee_number = e.employee_number 
       JOIN Employee e1 ON e1.employee_number = e.manager_number 
WHERE s.storeid=1 
GROUP BY e.employee_name 
ORDER BY SUM(p.total_sale_value) DESC LIMIT 1; 

以上查询仅显示单个商店的销售数据,原因如我所述WHERE s.storeid=1。我的桌子上有20家商店。如何更改上面的查询,以便为20个商店提供销售数据(这样就是20行)。

2 个答案:

答案 0 :(得分:1)

考虑为每个商店的每个员工使用 SalesValue 的排名变量,然后在外部查询中选择RANK=1

SELECT main.Store, main.Employee, main.Manager, main.SalesValue
FROM
 (SELECT agg.*,      
         @store:=agg.Store AS CURR_STORE,
         @rank:=CASE WHEN @val > agg.SalesValue THEN @rank+1 ELSE 1 END AS RANK,
         @val:=CASE WHEN @store <> agg.Store THEN @val ELSE agg.SalesValue END AS CURR_VAL
  FROM
    (SELECT s.storename AS "Store", 
            e.employee_name AS "Employee", 
            e1.employee_name AS "Manager", 
            SUM(p.total_sale_value) AS "SalesValue"
     FROM fss_Shop s 
     INNER JOIN Employee e ON e.storeid = s.storeid 
     INNER JOIN Payment p ON p.employee_number = e.employee_number 
     INNER JOIN Employee e1 ON e1.employee_number = e.manager_number  
     GROUP BY s.storename, 
              e.employee_name, 
              e1.employee_name
    ) As agg
  CROSS JOIN (SELECT @rank:= 0) AS r1
  CROSS JOIN (SELECT @val:= 0) AS r2
  CROSS JOIN (SELECT @store:= 0) AS r3
  ORDER BY agg.Store, agg.SalesValue DESC
 ) As main
WHERE main.RANK = 1; 

<强>样本

Rextester (使用只有一个Sales表的随机数据)

或者,如果无法使用变量,请考虑创建两个视图,其中后者引用前者:1)初始聚合查询,2)相关子查询以检索每个商店的最高员工

CREATE OR REPLACE VIEW sales_data AS 
SELECT s.storename AS "Store", 
       e.employee_name AS "Employee", 
       e1.employee_name AS "Manager", 
       SUM(p.total_sale_value) AS "SalesValue"
FROM fss_Shop s 
INNER JOIN Employee e ON e.storeid = s.storeid 
INNER JOIN Payment p ON p.employee_number = e.employee_number 
INNER JOIN Employee e1 ON e1.employee_number = e.manager_number  
GROUP BY s.storename, 
         e.employee_name, 
         e1.employee_name;

CREATE OR REPLACE VIEW top_sales_data AS 
SELECT s.*
FROM sales_data s 
WHERE (SELECT Count(*) FROM sales_data sub
       WHERE sub.SalesValue > s.SalesValue 
       AND sub.Store = s.Store) = 0;

答案 1 :(得分:1)

CREATE OR REPLACE VIEW employee_sales_totals AS
    SELECT
        e.*,
        SUM(p.total_sale_value)   AS total_sale_value
    FROM
        Employee e
    INNER JOIN
        Payment  p
            ON p.employee_number = e.employee_number 
    GROUP BY
        e.id  -- This should be the Primary Key / Surrogate Key of the employee table
;

CREATE OR REPLACE VIEW shop_top_employee_by_sales_value AS
    SELECT
        s.storename          AS "Store", 
        e.employee_name      AS "Employee", 
        m.employee_name      AS "Manager", 
        p.total_sale_value   AS "Sales Value" 
    FROM
    (
        SELECT storeid, MAX(total_sale_value) AS total_sale_value
          FROM employee_sales_totals
      GROUP BY storeid
    )
       p
    INNER JOIN
        employee_sales_totals   e
            ON  e.storeid          = p.storeid
            AND e.total_sale_value = p.total_sale_value
    INNER JOIN
        fss_Shop   s 
            ON s.storeid = e.storeid 
    INNER JOIN
        Employee   m
            ON m.employee_number = e.manager_number 
;

根据您之前提问的答案,如果多个员工在同一商店中的总销售额相同,则会退回所有此类员工。