MySQL – Как ограничить один результат на ID?

У меня есть следующий запрос, который создает таблицу представлений, показывающую наивысшего продавца в магазине с несколькими другими деталями:

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 как я сказал WHERE s.storeid=1 . У меня 20 магазинов в моем столе. Как изменить указанный выше запрос, чтобы он дал мне данные о продажах для 20 магазинов (так что это 20 строк).

 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 ; 

В соответствии с ответом на ваш предыдущий вопрос, если несколько сотрудников привязаны к той же общей сумме продаж в одном магазине, все такие сотрудники будут возвращены.

Рассмотрите возможность использования переменной рейтинга 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; 

DEMO

Rextester (используя случайные данные только с одной таблицей продаж)


В качестве альтернативы, если переменные не могут использоваться, рассмотрите возможность создания двух представлений, где последние ссылаются на первое: 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;