Как объединить 2 таблицы в одну с 2 полями MySQL

365
02 февраля 2018, 19:34

Подскажите, пожалуйста, как составить запрос. Мне необходимо из 2 таблиц выбрать одинаковые значения полей userid и fuserid.

SELECT a.userid, b.fuserid FROM users, fusers WHERE a.userid=457281
AND b.fuserid=457281

выдает пустые поля [userid][fuserid], хотя в users имеется 2 значения, в таблице fuserid пока не имеется значений

SELECT a.userid, b.fuserid FROM users RIGHT JOIN fusers ON    
a.userid=457281 AND b.fuserid=457281

также выдает пустые поля [userid][fuserid]

SELECT a.userid, b.fuserid FROM users LEFT JOIN fusers ON a.userid=457281  
AND b.fuserid=457281

выдает ненужное поле, к пример:

[userid][fuserid]
[457281][NULL]
[457281][NULL]
[391419][NULL] 

лишнее поле, которое не нужно

SELECT a.userid, b.fuserid FROM users JOIN fusers ON a.userid=457281
AND b.fuserid=457281

выдает пустые поля

Пи объединении с помощью UNION

(SELECT a.userid FROM users WHERE  a.userid=457281) UNION (SELECT
b.fuserid FROM fusers WHERE  b.fuserid=457281)

выдает одну колонку, имеющую значение 457281, в данном случае [userid]

Мне нужно, чтоб из 2-х таблиц выбирались одинаковые записи и показывались в разных колонках.
Типа:

[457281][457281] или 
[NULL][457281] или 
[457281][NULL]

Как этого можно добиться?

Answer 1
SELECT max(userid) userid, max(fuserid) fuserid
  FROM (
    SELECT userid as id, userid, NULL as fuserid
      FROM users
     WHERE userid=457281
    UNION ALL
    SELECT fuserid     , NULL  , fuserid
      FROM fusers
     WHERE fuserid=457281
  ) X
  GROUP BY id

Если убрать условия на отбор конкретного id в таблицах, можно получить выборку по всем id, в которой будет видно какие из них присутствуют в какой из таблиц.

Answer 2

Из вопроса непонятно, какой из двух случаев вам нужен.

Если вам нужно выбирать значение только тогда, когда оно есть в обоих таблицах, то проще всего сделать уже приведенный INNER JOIN

SELECT u.userid, f.fuserid
FROM users AS u
INNER JOIN fusers AS f ON u.userid = f.fuserid AND f.fuserid = ?

Однако т.к. сам ID вам очевидно известен и вы явно проверяете только наличие записи, проще обратиться к соответствующим операторам

SELECT 1 
WHERE EXISTS (SELECT * FROM users AS u WHERE u.userid = ?) 
AND EXISTS (SELECT * FROM fusers AS f WHERE f.fuserid = ?)

Так запрос хотя бы сам по себе будет объяснять свое существование

В случае, если вам нужно проверить, есть ли это значение хотя бы в одной таблице, достаточно сделать FULL OUTER JOIN

SELECT COALESCE(u.userid, f.fuserid) AS result
FROM users AS u
FULL OUTER JOIN fusers AS f ON u.userid = f.fuserid AND f.fuserid = ?

Т.к. как верно замечают рядом, OUTER JOIN в MySQL еще не завезли, его можно грубо эмулировать через UNION

SELECT COALESCE(cte.userid, cte.fuserid) AS result 
FROM (
  SELECT u.userid, f.fuserid
  FROM users AS u
  LEFT JOIN fusers AS f ON u.userid = f.fuserid AND f.fuserid = ?
  UNION
  SELECT u.userid, f.fuserid
  FROM users AS u
  RIGHT JOIN fusers AS f ON u.userid = f.fuserid AND f.fuserid = ?
)

В этом случае вам вернется либо ноль строк, либо одна строка с одним полем.

EXISTS все так же работает (внимание на логический оператор):

SELECT 1 
WHERE EXISTS (SELECT * FROM users AS u WHERE u.userid = ?) 
OR EXISTS (SELECT * FROM fusers AS f WHERE f.fuserid = ?)

Если же для вас критично получить результат или null, что, конечно, немного издевательски по отношению к SQL, достаточно будет прибегнуть к небольшому хаку:

SELECT COALESCE(u.userid, f.fuserid) AS result
FROM users AS u
INNER JOIN fusers AS f ON u.userid = f.fuserid AND f.fuserid = ?
UNION
SELECT null AS result

Можно даже принудить SQL возвращать ровно одну строку:

SELECT * FROM (
  SELECT COALESCE(u.userid, f.fuserid) AS result
  FROM users AS u
  INNER JOIN fusers AS f ON u.userid = f.fuserid AND f.fuserid = ?
  UNION
  SELECT null AS result
) AS cte LIMIT 1

Но все это суть издевательство, и я бы все-таки посмотрел на EXISTS.

Answer 3

Вроде как-то так:

SELECT distinct a.userid, b.fuserid
FROM users a, fusers b
WHERE a.userid = 457281 AND (b.fuserid = 457281 OR b.fuserid is null)
      OR (a.userid = 457281 OR a.userid is null) AND b.fuserid = 457281
Answer 4

Как я понял, нужна для каждого ID только одна запись (посмотреть, есть ли записи в какой-то одной или обеих таблицах).

Поскольку MySQL не знает про FULL OUTER JOIN, то, видимо

SELECT DISTINCT t1.userid, t2.fuserid
FROM (  SELECT userid u FROM users
        UNION
        SELECT fuserid FROM fusers
     ) t0
LEFT JOIN users t1 ON t0.u = t1.userid
LEFT JOIN fusers t2 ON t0.u = t2.fuserid
-- WHERE t0.u IN (список интересующих ID)

WHERE можно при желании убрать в подзапрос - если список мал, а записей много, это даст эффект.

Если интересует строго один ID, подзапрос t0 заменить на

( SELECT 123456 u ) t0
Answer 5
SELECT users.userID, fusers.fuserID
FROM users
INNER JOIN fusers ON users.userID = 1 and fusers.fuserID = 1
Answer 6

Во всех ваших запросах вы забыли поставить алиасы на таблицы. Вот рабочий запрос

SELECT a.userid, b.fuserid FROM users a, fusers b WHERE a.userid=457281
AND b.fuserid=457281

или как вам уже ответили с добавлением условия

SELECT u1.id as u1_id, u2.id as u2_id FROM users u1
JOIN fusers u2 ON u1.id = u2.id
WHERE u1.id = 457281;
READ ALSO
Инкремент в запросе UPDATE MySQL

Инкремент в запросе UPDATE MySQL

В БД имеется 3 столбцаНеобходимо сдвинуть записи во 2 столбце на 1 строку

212
SELECT и выборка из другой таблицы

SELECT и выборка из другой таблицы

Довольно простой запрос, только мне ещё нужно получить дополнительное поле sub_count, которое берется при помощи COUNT(*) из другой таблицы

276
BackgroundWorker

BackgroundWorker

vkMessages

295