如何在mysql

时间:2019-06-16 12:10:22

标签: mysql join left-join inner-join right-join

Ï需要对同一张表的两个选择(顶行和底行)进行联接,但是内部联接返回一个空集。我不知道这怎么可能,因为我正在对两个表都相同的新列进行联接。

以下是底行表和顶行表的选择子查询:

底部行:

select @n := @n + 1 row_number, st.* from (select @n:=0) init, strmrs st where timestamp between 1514764860 and 1517443140 order by timestamp desc, username limit 10;

给出结果:

+------------+----------+------------+-------+---------+-----------+
| row_number | username | timestamp  | game  | viewers | followers |
+------------+----------+------------+-------+---------+-----------+
|          1 | user1    | 1517443140 | game1 |       3 |     44669 |
|          2 | user2    | 1517443081 | game2 |       5 |     44668 |
|          3 | user1    | 1517443080 | game1 |       3 |     44668 |
|          4 | user2    | 1517443021 | game2 |       5 |     44667 |
|          5 | user1    | 1517443020 | game1 |       3 |     44667 |
|          6 | user2    | 1517442961 | game2 |       5 |     44666 |
|          7 | user1    | 1517442960 | game1 |       3 |     44666 |
|          8 | user2    | 1517442901 | game2 |       5 |     44665 |
|          9 | user1    | 1517442900 | game1 |       3 |     44665 |
|         10 | user2    | 1517442841 | game2 |       5 |     44664 |
+------------+----------+------------+-------+---------+-----------+

顶行:

select @n := @n + 1 row_number, st.* from (select @n:=0) init, strmrs st where timestamp between 1514764860 and 1517443140 order by timestamp, username limit 10;

给出结果:

+------------+----------+------------+-------+---------+-----------+
| row_number | username | timestamp  | game  | viewers | followers |
+------------+----------+------------+-------+---------+-----------+
|          1 | user1    | 1514764860 | game1 |       3 |        31 |
|          2 | user2    | 1514764861 | game2 |       5 |        31 |
|          3 | user1    | 1514764920 | game1 |       3 |        32 |
|          4 | user2    | 1514764921 | game2 |       5 |        32 |
|          5 | user1    | 1514764980 | game1 |       3 |        33 |
|          6 | user2    | 1514764981 | game2 |       5 |        33 |
|          7 | user1    | 1514765040 | game1 |       3 |        34 |
|          8 | user2    | 1514765041 | game2 |       5 |        34 |
|          9 | user1    | 1514765100 | game1 |       3 |        35 |
|         10 | user2    | 1514765101 | game2 |       5 |        35 |
+------------+----------+------------+-------+---------+-----------+

我的问题是两个表的内部联接结果都为空集,而左联接或右联接都在相对侧给出了空列。例如:

select late.row_number, early.row_number, early.username as early_users, late.username as late_users, early.followers as early_followers, late.followers as late_followers from 
(select @n := @n + 1 row_number, st.* from (select @n:=0) init, strmrs st where timestamp between 1514764860 and 1517443140 order by timestamp desc, username limit 10) late 
left join 
(select @n := @n + 1 row_number, st.* from (select @n:=0) init, strmrs st where timestamp between 1514764860 and 1517443140 order by timestamp, username limit 10) early 
on late.row_number = early.row_number;

返回:

+------------+------------+-------------+------------+-----------------+----------------+
| row_number | row_number | early_users | late_users | early_followers | late_followers |
+------------+------------+-------------+------------+-----------------+----------------+
|          1 |       NULL | NULL        | user1      |            NULL |          44669 |
|          2 |       NULL | NULL        | user2      |            NULL |          44668 |
|          3 |       NULL | NULL        | user1      |            NULL |          44668 |
|          4 |       NULL | NULL        | user2      |            NULL |          44667 |
|          5 |       NULL | NULL        | user1      |            NULL |          44667 |
|          6 |       NULL | NULL        | user2      |            NULL |          44666 |
|          7 |       NULL | NULL        | user1      |            NULL |          44666 |
|          8 |       NULL | NULL        | user2      |            NULL |          44665 |
|          9 |       NULL | NULL        | user1      |            NULL |          44665 |
|         10 |       NULL | NULL        | user2      |            NULL |          44664 |
+------------+------------+-------------+------------+-----------------+----------------+

什么时候,我想得到的是:

+------------+------------+-------------+------------+-----------------+----------------+
| row_number | row_number | early_users | late_users | early_followers | late_followers |
+------------+------------+-------------+------------+-----------------+----------------+
|          1 |          1 | user1       | user1      |              31 |          44669 |
|          2 |          2 | user2       | user2      |              31 |          44668 |
|          3 |          3 | user1       | user1      |              32 |          44668 |
|          4 |          4 | user2       | user2      |              32 |          44667 |
|          5 |          5 | user1       | user1      |              33 |          44667 |
|          6 |          6 | user2       | user2      |              33 |          44666 |
|          7 |          7 | user1       | user1      |              34 |          44666 |
|          8 |          8 | user2       | user2      |              34 |          44665 |
|          9 |          9 | user1       | user1      |              35 |          44665 |
|         10 |         10 | user2       | user2      |              35 |          44664 |
+------------+------------+-------------+------------+-----------------+----------------+

有人可以告诉我我做错了什么/如何实现我想要的吗?

非常感谢您:)

1 个答案:

答案 0 :(得分:0)

首先,这与任何事情都没有关系,您不是在进行内部联接,而是在进行外部联接。

我希望我能对为什么在执行外部联接时,计算出的行号与实际数据库列的行为方式不一样的问题做出明确的解释,但事实确实如此。因此,您应该创建临时表,其中这些计算的行号将变为实际的列:

CREATE TEMPORARY TABLE late as
    select @n := @n + 1 row_number, st.* from (select @n:=0) init, strmrs st where timestamp between 1514764860 and 1517443140 order by timestamp desc, username limit 10;

CREATE TEMPORARY TABLE early as
    select @n := @n + 1 row_number, st.* from (select @n:=0) init, strmrs st where timestamp between 1514764860 and 1517443140 order by timestamp, username limit 10;

select late.row_number, early.row_number, early.username as early_users, late.username as late_users, early.followers as early_followers, late.followers as late_followers from
late l JOIN early on late.row_number = early.row_number;

现在行号在实际的列中,因此无需进行外部联接;内部联接就足够了。如果您使用不带临时表的内部联接,则不会返回任何行,这可能就是您诉诸外部联接的原因。

顺便说一句,如果您需要在程序中处理这些值,那么使用唯一列名的建议就变得至关重要。

如果要联接许多行(此处每个表中只有10行),则可以考虑在临时表的row_number列上创建索引,可能只是将它们定义为主键。