Группировать все строки после n-го ряда вместе - PullRequest
2 голосов
/ 16 апреля 2019

У меня есть текущая таблица:

+----------+-------+
| salesman | sales |
+----------+-------+
|        1 |   142 |
|        2 |   120 |
|        3 |   176 |
|        4 |   140 |
|        5 |   113 |
|        6 |   137 |
|        7 |   152 |
+----------+-------+

Я хотел бы сделать запрос, чтобы получить 3 лучших продавца и столбец «Другое», который будет суммой всех остальных.Ожидаемый результат будет:

+----------+-------+
| salesman | sales |
+----------+-------+
| 3        |   176 |
| 7        |   152 |
| 1        |   142 |
| Others   |   510 |
+----------+-------+

Я использую MySQL, и у меня есть опыт в этом, но я не могу себе представить способ сделать этот вид GROUP BY.

Испытанный UNION с 2 SELECT, один для 3 лучших продавцов и другой выбор для "Других", но я не мог найти способ исключить 3 лучших из 2 SELECT

Ответы [ 5 ]

3 голосов
/ 16 апреля 2019

Вы можете сделать это, LEFT JOIN добавив свою таблицу в список 3 лучших продавцов, а затем сгруппировавшись по номеру COALESCE d продавца из 3 верхних таблиц (который будет NULL, если продавец не в топе 3).

SELECT COALESCE(top.sman, 'Others') AS saleman,
       SUM(sales) AS sales
FROM test
LEFT JOIN (SELECT salesman AS sman
           FROM test
           ORDER BY sales DESC
           LIMIT 3) top ON top.sman = test.salesman
GROUP BY saleman
ORDER BY saleman = 'Others', sales DESC

Выход:

saleman sales
3       176
7       152
1       142
Others  510

Демонстрация по dbfiddle

2 голосов
/ 16 апреля 2019

Это боль в MySQL:

(select salesman, count(*) as cnt
 from t
 group by salesman
 order by count(*), salesman
 limit 3
) union all
(select 'Others', count(*)
 from t left join
      (select salesman, count(*) as cnt
       from t
       group by salesman
       order by count(*)
       limit 3
      ) t3
      on t3.salesman = t.salesman
 where t3.salesman is null
);
2 голосов
/ 16 апреля 2019

Используя операторы UNION, ORDER BY, LIMIT, OFFSET И GROUP BY, вы должны сделать трюк:

SELECT salesman, sales 
FROM t 
ORDER BY sales DESC LIMIT 3
UNION
SELECT 'Others', SUM(sales) 
FROM (SELECT salesman, sales 
      FROM t 
      ORDER BY sales DESC LIMIT 3, 18446744073709551615) AS tt;

Большое число в конце - это способ применения лимита до конца таблицы, как предлагается здесь

1 голос
/ 16 апреля 2019

Это должно быть самым быстрым при наличии соответствующих индексов :

(
    SELECT salesman, sales
    FROM t
    ORDER BY sales DESC
    LIMIT 3
)
UNION ALL
(
    SELECT 'Other', SUM(sales) - (
        SELECT SUM(sales)
        FROM (
            SELECT sales
            FROM t
            ORDER BY sales DESC
            LIMIT 3
        ) AS top3
    )
    FROM t
)
ORDER BY CASE WHEN salesman = 'Other' THEN NULL ELSE sales END DESC
0 голосов
/ 16 апреля 2019

это будет работать:

select salesman,sales from tablename a where a.salesman in (3,7,1) 
union all
select 'others' as others,sum(a.sales) as sum_of_others from tablename a where 
a.salesman not in (3,7,1) group by others;

check https://www.db -fiddle.com / f / 73GjFXL3KsZsYnN26g3rS2 / 0

...