Как объединить два выбора из одной таблицы в MySQL - PullRequest
1 голос
/ 16 июня 2019

Ï необходимо объединить два выбора одной и той же таблицы (верхняя и нижняя строки), но внутреннее объединение возвращает пустой набор. Я не понимаю, как это возможно, поскольку я выполняю объединение для нового столбца, который одинаков для обеих таблиц.

Вот подзапросы выбора для таблиц нижней строки и верхней строки:

нижние ряды:

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 голосов
/ 17 июня 2019

Прежде всего, и это не имеет ничего общего, вы не делаете ВНУТРЕННЕЕ СОЕДИНЕНИЕ, а скорее ВНЕШНЕЕ СОЕДИНЕНИЕ.

Хотелось бы, чтобы у меня было четкое объяснение, почему вычисленные номера строк не ведут себя так же, как фактические столбцы базы данных при выполнении внешних объединений, но, похоже, это так. Поэтому вы должны создавать временные таблицы, в которых эти вычисленные номера строк станут фактическими столбцами:

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 временных таблиц, возможно, просто определив их как первичные ключи.

...