mysql - LEFT JOIN 的行为不如预期,因为在 MySQL 中给出 NULL

标签 mysql pivot-table

我正在完成 this challenge来自 HackerRank。

它问:

旋转 OCCUPATIONS 中的职业列,以便每个名称按字母顺序排序并显示在其对应的职业下方。输出列标题应分别为 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 旋转此表,以便每个 Name 按字母顺序排序并显示在其对应的 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 的行为方式是否使您不能对多个表进行编号?我不清楚。

最佳答案

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

我测试了它,只是连接了前两个(教授和医生),但是使用了交叉连接,所以我可以看到所有的 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     |
+------------+-----------+--------+-----------+----------+

关于mysql - LEFT JOIN 的行为不如预期,因为在 MySQL 中给出 NULL,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46210995/

相关文章:

mysql - 如何在sql中使用join连接两个表?

javascript - 从 HTML 表到 mysql 数据库

php - 如何在条件下使用 ARRAY 查询 mysql

mysql - 宏无法获取正确的数据透视表名称

matlab - 根据 Matlab 中单元格的现有列创建新变量

excel - 创建一个可重复的数据透视表,加载到同一个工作表上

mysql - 连接字符串修改(替换、连接、修剪)

php - MySQL/PHP 从多列中仅选择唯一值并将它们放入单独的数组中

excel - 如何使用数据透视表为每个子类别创建一行

google-sheets - 我可以使用第二个条件订购数据透视表吗?