LEFT JOIN没有像预期的那样表现为在MySQL

时间:2017-09-14 05:12:51

标签: mysql pivot-table

我正在从HackerRank完成this challenge

它问道:

旋转OCCUPATIONS中的Occupation列,以便每个Name按字母顺序排序并显示在其相应的Occupation下面。输出列标题应分别为Doctor,Professor,Singer和Actor。

它涉及这个数据表:

Name       Occupation     
Ashley      Professor 
Samantha Actor 
Julia         Doctor 
Britney     Professor 
Maria        Professor 
Meera       Professor 
Priya         Doctor 
Priyanka    Professor 
Jennifer     Actor 
Ketty         Actor 
Belvet Professor 
Naomi Professor 
Jane Singer 
Jenny Singer 
Kristeen Singer 
Christeen Singer 
Eve Actor 
Aamina Doctor

我们希望将此表格按Occupation进行调整,以便每个名称按字母顺序排序并显示在其相应的职业下方。输出列标题(实际上并非如此)应分别为Doctor,Professor,Singer和Actor。

但是,当我运行这个MySQL代码时:

SELECT d.name, p.name, s.name, a.name 
FROM (
    SELECT @row_number:=@row_number+1 AS row_number, Name
    FROM OCCUPATIONS, (SELECT @row_number:=0) AS t
    WHERE Occupation = 'Professor'
    ORDER BY Name
    ) p
LEFT JOIN (
    SELECT @row_number:=@row_number+1 AS row_number, Name
    FROM OCCUPATIONS, (SELECT @row_number:=0) AS t
    WHERE Occupation = 'Doctor'
    ORDER BY Name
    ) d ON d.row_number =p.row_number
LEFT JOIN (
    SELECT @row_number:=@row_number+1 AS row_number, Name
    FROM OCCUPATIONS, (SELECT @row_number:=0) AS t
    WHERE Occupation = 'Singer'
    ORDER BY Name
    ) s ON p.row_number =s.row_number
LEFT JOIN (
    SELECT @row_number:=@row_number+1 AS row_number, Name
    FROM OCCUPATIONS, (SELECT @row_number:=0) AS t
    WHERE Occupation = 'Actor'
    ORDER BY Name
    ) a ON p.row_number =a.row_number

LEFT JOIN没有按预期行事,我得到:

NULL Ashley NULL NULL 
NULL Belvet NULL NULL 
NULL Britney NULL NULL 
NULL Maria NULL NULL 
NULL Meera NULL NULL 
NULL Naomi NULL NULL 
NULL Priyanka NULL NULL

这对我没有意义 - 为什么连接会产生这么多空值? MySQL的行为方式是否能够为多个表编号?我不清楚。

1 个答案:

答案 0 :(得分:2)

我认为它与您认为应该的方式不匹配的原因是@row_number不会为每个子查询重置为1。

我测试了它,只是加入前两个(教授和医生),但使用CROSS JOIN,所以我可以看到所有row_number值。

+------------+--------+------------+----------+
| row_number | name   | row_number | name     |
+------------+--------+------------+----------+
|          8 | Aamina |          1 | Ashley   |
|          8 | Aamina |          2 | Belvet   |
|          8 | Aamina |          3 | Britney  |
|          8 | Aamina |          4 | Maria    |
|          8 | Aamina |          5 | Meera    |
|          8 | Aamina |          6 | Naomi    |
|          8 | Aamina |          7 | Priyanka |
|          9 | Julia  |          1 | Ashley   |
|          9 | Julia  |          2 | Belvet   |
|          9 | Julia  |          3 | Britney  |
|          9 | Julia  |          4 | Maria    |
|          9 | Julia  |          5 | Meera    |
|          9 | Julia  |          6 | Naomi    |
|          9 | Julia  |          7 | Priyanka |
|         10 | Priya  |          1 | Ashley   |
|         10 | Priya  |          2 | Belvet   |
|         10 | Priya  |          3 | Britney  |
|         10 | Priya  |          4 | Maria    |
|         10 | Priya  |          5 | Meera    |
|         10 | Priya  |          6 | Naomi    |
|         10 | Priya  |          7 | Priyanka |
+------------+--------+------------+----------+

您可以看到显然行号逐渐递增,两个子查询中的初始值1已经在行编号时完成。

您可以通过在每个子查询中使用不同的用户变量来解决此问题。

但是这个查询无论如何都不会以你想要的方式运作,例如你的教授人数比其他职业的人少。

老实说,我不会在SQL中进行这种列式格式化。只需执行四个独立查询,将所有结果提取到应用程序中,并在输出时格式化为列。这样会简单得多,简单的代码更容易编写,更容易调试,更易于维护。

重新评论:

很公道,这样做是一个编码挑战很好,只要你(和其他读者)知道在一个真实的项目中,做一些过于聪明的SQL并不总是最好的想法。

由于您正在进行编码挑战,您应该自己解决,因此我无法为您提供产生以下输出的解决方案。但这证明它是可能的(我保证我没有模拟输出,我真的从终端窗口复制和粘贴它)。祝你好运!

+------------+-----------+--------+-----------+----------+
| row_number | Professor | Doctor | Singer    | Actor    |
+------------+-----------+--------+-----------+----------+
|          1 | Ashley    | Aamina | Christeen | Eve      |
|          2 | Belvet    | Julia  | Jane      | Jennifer |
|          3 | Britney   | Priya  | Jenny     | Ketty    |
|          4 | Maria     | NULL   | Kristeen  | Samantha |
|          5 | Meera     | NULL   | NULL      | NULL     |
|          6 | Naomi     | NULL   | NULL      | NULL     |
|          7 | Priyanka  | NULL   | NULL      | NULL     |
+------------+-----------+--------+-----------+----------+
相关问题