SQL - UNION没有订购第二个SELECT

时间:2017-02-14 23:44:24

标签: mysql union

我正试图解决这个挑战: https://www.hackerrank.com/challenges/the-pads

我的解决方案是MySQL:

(SELECT CONCAT(Name,'(',SUBSTR(Occupation,1,1),')') FROM Occupations ORDER BY Name)
UNION
(SELECT CONCAT('There are total ', COUNT(Occupation), ' ',LOWER(Occupation),'s.') AS total FROM Occupations 
GROUP BY Occupation 
ORDER BY total);

然而,它没有按顺序排序。

Ashley(P) 
Samantha(A) 
Julia(D) 
Britney(P) 
Maria(P) 
Meera(P) 
Priya(D) 
Priyanka(P) 
Jennifer(A) 
Ketty(A) 
Belvet(P) 
Naomi(P) 
Jane(S) 
Jenny(S) 
Kristeen(S) 
Christeen(S) 
Eve(A) 
Aamina(D) 
There are total 4 actors. 
There are total 3 doctors. 
There are total 7 professors. 
There are total 4 singers. 

如果我只运行

SELECT CONCAT('There are total ', COUNT(Occupation), ' ',LOWER(Occupation),'s.') AS total FROM Occupations 
GROUP BY Occupation 
ORDER BY total

它确实有序:

There are total 3 doctors. 
There are total 4 actors. 
There are total 4 singers. 
There are total 7 professors. 

5 个答案:

答案 0 :(得分:2)

结果按最终ORDER BY子句排序。这是ORDER BY total,即第一列。 (您只在UNION的第二部分中提供此名称,这可能不适用于另一个DBMS。您应该在第一部分的UNION查询中命名您选择的列。)

您希望先获取名称,然后获取聚合。那么你想要按字母顺序排列名称,按照计数聚合(即按字母顺序排列,不是1 - > 10 - > 11>> 2 - > 20 ...,但是1 - > 2 - > 10 - > 11 - > 20 ...)然后按作业名称。您可以为此任务创建排序键。我假设你真的想要UNION ALL,而不是UNION。如果我错了,改变它: - )

SELECT txt
FROM
(
  SELECT 
    CONCAT(Name, '(', SUBSTR(Occupation, 1, 1), ')') as txt,
    1 as sortkey1,
    CONCAT(Name, '(', SUBSTR(Occupation, 1, 1), ')') as sortkey2
  FROM Occupations
  UNION ALL
  SELECT 
    CONCAT('There are total ', COUNT(Occupation), ' ', LOWER(Occupation), 's.') AS txt,
    2 + COUNT(Occupation) as sortkey1,
    LOWER(Occupation) as sortkey2
  FROM Occupations 
  GROUP BY Occupation 
) data
ORDER BY sortkey1, sortkey2;

答案 1 :(得分:1)

这是正确的。结果集的排序仅基于最外层order by 。对于union和其他操作一样。

(SELECT CONCAT(Name,'(', SUBSTR(Occupation,1,1),')') AS total
 FROM Occupations
 ORDER BY Name
)
UNION ALL
(SELECT CONCAT('There are total ', COUNT(Occupation), ' ', LOWER(Occupation), 's.') AS total
 FROM Occupations 
 GROUP BY Occupation 
)
ORDER BY (CASE WHEN total LIKE 'There are total%' THEN 1 ELSE 0 END),
         Total;

这假定Name永远不会以'There are total'开头,这似乎很可能。

答案 2 :(得分:1)

@gordon回答很好

但是对于更通用的情况,你必须创建一个“虚拟”字段来分隔每个组。

(SELECT CONCAT(Name,'(', SUBSTR(Occupation,1,1),')') as Name,
        0 as dummy
 FROM Occupations
)
UNION ALL
(SELECT CONCAT('There are total ', COUNT(Occupation), ' ', LOWER(Occupation), 's.') AS Name,
        1 as dummy
 FROM Occupations 
 GROUP BY Occupation 
)
ORDER BY dummy, name

答案 3 :(得分:0)

根据答案和我的最佳理解,我找到了适合此案例的解决方案:

    (SELECT CONCAT(Name,'(',SUBSTR(Occupation,1,1),')') as total FROM Occupations ORDER BY Name)
UNION ALL
(SELECT CONCAT('There are total ', COUNT(Occupation), ' ',LOWER(Occupation),'s.') AS total FROM Occupations 
GROUP BY Occupation) 
ORDER BY total;

答案 4 :(得分:0)

这对我有用。 您可以通过UNION / UNION ALL给出两个不同的选择查询。

SELECT Concat(NAME, '(', Substr(occupation, 1, 1), ')') AS Result 
FROM occupations 
ORDER  BY NAME;


SELECT Concat('There are a total of ', Count(*), ' ', Lower(occupation), 's.') 
FROM   occupations 
GROUP  BY occupation 
ORDER  BY Count(*), occupation;