将所有行排在第n行之后

时间:2019-04-16 12:47:01

标签: mysql sql aggregate-functions

我有当前表:

+----------+-------+
| 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名推销员,另一个是“其他”推销员,但我想不出从第二个{ {1}}

5 个答案:

答案 0 :(得分:3)

您可以LEFT JOIN将表格归到前三位推销员的列表中,然后将前三位表中的COALESCE d位推销员号码分组(即{{1 }}(如果推销员不在前3名)。

NULL

输出:

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

Demo on dbfiddle

答案 1 :(得分:2)

使用UNIONORDER BYLIMITOFFSETGROUP 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;

按照建议here

,末尾的大数字是应用限制直到表格末尾的方式

答案 2 :(得分:2)

这在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
);

答案 3 :(得分:1)

如果存在适当的索引,这应该是最快的一种:

(
    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

答案 4 :(得分:0)

这将起作用:

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;

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