如何选择第n行以最后记录sql?

时间:2019-12-02 12:59:08

标签: mysql sql

我遇到这样的情况,我必须显示前9行,其中包含电子邮件的域名,而没有出现电子邮件,而第10行显示为其余域的总和,并显示为其他域。

我做了什么。

我已经成功使用以下查询获得了不同的域及其出现的位置

SELECT (SUBSTRING_INDEX(SUBSTR(email, INSTR(email, '@') + 1),'.',1)) as domain,
       COUNT(*) as C
FROM newsletter_recipient
where LENGTH(email) > 0
GROUP BY (SUBSTRING_INDEX(SUBSTR(email, INSTR(email, '@') + 1),'.',1))
ORDER BY COUNT(*) DESC

当前结果

domain           C
------------------------    
gmail           12  
dddd            2   
mmmmm           2   
dsf             2   
aaaa            1   
bbbb            1   
ccc             1   
yopmail         1   
yahoo           1   
dde             1   
rfg             1   
eedd            1   
dfdg            1   
sad             1   
dfdf            1   
sfd             1   
web             1   

预期结果

domain           C
------------------------    
gmail           12  
dddd            2   
mmmmm           2   
dsf             2   
aaaa            1   
bbbb            1   
ccc             1   
yopmail         1   
yahoo           1
others          8

希望有人可以帮助

4 个答案:

答案 0 :(得分:1)

使用两种聚合级别:

stream.collect(Collectors.groupingBy(s -> getAnagramKey(s)))
    .values().stream()
    .filter(l -> l.size() > 1)
    .sorted(Collections.reverseOrder(Comparator.comparingInt(List::size)))
    .limit(10)
    .forEach(System.out::println);

答案 1 :(得分:0)

使用case when expression-

SELECT case when (SUBSTRING_INDEX(SUBSTR(email, INSTR(email, '@') + 1),'.',1)) 
not in ('gmail','dddd','mmmmm','dsf','aaaa','bbbb','ccc','yopmail','yahoo') then 'Other'
else (SUBSTRING_INDEX(SUBSTR(email, INSTR(email, '@') + 1),'.',1)) as domain,
       COUNT(*) as C
FROM newsletter_recipient
where LENGTH(email) > 0
GROUP BY case when (SUBSTRING_INDEX(SUBSTR(email, INSTR(email, '@') + 1),'.',1)) 
not in ('gmail','dddd','mmmmm','dsf','aaaa','bbbb','ccc','yopmail','yahoo') then 'Other'
else (SUBSTRING_INDEX(SUBSTR(email, INSTR(email, '@') + 1),'.',1))
ORDER BY COUNT(*) DESC

答案 2 :(得分:0)

您可以尝试以下

WITH cte AS (
     SELECT (SUBSTRING_INDEX(SUBSTR(email, INSTR(email, '@') + 1),'.',1)) as domain,
     COUNT(*) as C
     FROM newsletter_recipient
     WHERE LENGTH(email) > 0
     GROUP BY (SUBSTRING_INDEX(SUBSTR(email, INSTR(email, '@') + 1),'.',1))
     ORDER BY COUNT(*) DESC
)
SELECT 
     IF(rn < 10, domain, 'others') AS domain_name,
     SUM(c) AS count
FROM (
     SELECT domain, c, ROW_NUMBER() OVER () AS rn FROM cte
) T
GROUP BY domain_name

DEMO HERE

答案 3 :(得分:0)

我会用联盟的前10个或其他形式解决这个问题:

SELECT * from (

SELECT 
    (SUBSTRING_INDEX(SUBSTR(email, INSTR(email, '@') + 1),
            '.',
            1)) AS domain,
    COUNT(*) AS C
FROM
     newsletter_recipient
WHERE
    LENGTH(email) > 0
GROUP BY (SUBSTRING_INDEX(SUBSTR(email, INSTR(email, '@') + 1),
        '.',
        1))
ORDER BY COUNT(*) DESC
Limit 10) as FIRST_10

UNION 

SELECT 'others', sum(ALL_OTHERS.C) from (

SELECT 
    COUNT(*) AS C
FROM
    newsletter_recipient
WHERE
    LENGTH(email) > 0
GROUP BY (SUBSTRING_INDEX(SUBSTR(email, INSTR(email, '@') + 1),
        '.',
        1))
ORDER BY COUNT(*) DESC
Limit 11,18446744073709551615
) as ALL_OTHERS

18446744073709551615:足够大,可以跳过前10个并确保检索其他所有内容,请参见:MySQL skip first 10 results