MySQL - How to limit one result per ID?

前端 未结 2 462
悲哀的现实
悲哀的现实 2021-01-23 01:40

I have the following query which creates a view table showing the highest salesperson in a store with few other details:

CREATE OR REPLACE VIEW sales_data AS 
SE         


        
2条回答
  •  不思量自难忘°
    2021-01-23 02:32

    Consider using a ranking variable by SalesValue for each employee per store and then choose the RANK=1 in outer query:

    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; 
    

    DEMO

    Rextester (using random data with only one Sales table)


    Alternatively, if variables cannot be used, consider creating two views where latter references the former: 1) initial aggregate query, 2) correlated subquery to retrieve top employee per store

    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;
    

提交回复
热议问题