2017-02-14 49 views
0

我真的试图解决这一难题: https://www.hackerrank.com/challenges/the-padsSQL - UNION不下令第二选择

我的解决办法是这样的在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); 

但是它没有ORDER BY总。

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. 
+0

一个侧面说明:'UNION'是从结果中删除重复项。你甚至有重复?该查询没有提示。可能你可以用简单的'UNION ALL'来完成,从而节省执行时间。 –

回答

1

这是正确的。结果集的排序仅基于在最外面的order byunion对于其他操作也是如此。

(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'开始,这可能看起来。

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 
+0

谢谢!所以在这里我有两列,对吧?一个与虚拟和其他CONCAT结果? – Pavel

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; 
+0

花了我一会儿了解'2 + COUNT(职业)'为'sortkey1',是为了什么。但非常好。 –

+0

谢谢Thorsten!它的工作原理,但你可以请详细解释它吗? 1-为什么在firts选择你显然是相同的CONCAT twise? 2-什么是1 sortkey1? 3-为什么选择2 + CONCAT? – Pavel

+0

**首先选择:**第一个concat用于显示文本,第二个用于排序。所以order会把所有的'1''放在一起,然后按sortkey2进行排序。**第二选择:** 2 + COUNT(职业)2是这个组中的每个人都在第一个'1'之后,然后是'count',是在'因为如果按文本排序''10'>'2'' –

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;