Как получить объединение в подзапросе MySQL Laravel? - PullRequest
0 голосов
/ 05 мая 2020

Я пытаюсь выполнить подзапрос в Laravel, чтобы получить некоторые релевантные данные пользователя, но данные могут быть в одной из двух таблиц. У меня есть таблица для test_activity и live_activity, у которых есть столбец created_at. Моя цель - получить самую старую запись из комбинации данных из двух таблиц.

Примеры данных:

CREATE TABLE users (
  id INTEGER, 
  first_name TEXT,
  last_name TEXT
 );

INSERT INTO users (id, first_name, last_name)
VALUES (1, 'Craig', 'Smith'), (2, 'Bill', 'Nye'), (3, 'Bloop', 'Blop');

CREATE TABLE test_activity (
  id INTEGER,
  user_id INTEGER,
  created_at DATE
 );

INSERT INTO test_activity (id, user_id, created_at)
VALUES (1, 1, '2019-04-29'), (2, 2, '2019-03-28'), (3, 3, '2019-04-28');

 CREATE TABLE live_activity (
  id INTEGER,
  user_id INTEGER,
  created_at DATE
 );

INSERT INTO live_activity (id, user_id, created_at)
VALUES (1, 1, '2019-04-27'), (2, 2, '2019-03-29'), (3, 3, '2019-04-27');

Вот как я пытаюсь выполнить запрос с Laravel:

$firstActivity = TestActivity::select('created_at')
            ->whereColumn('user_id', 'id');

$firstActivity = LiveActivity::select('created_at')
            ->whereColumn('user_id', 'id')
            ->union($firstActivity)
            ->limit(1)
            ->getQuery();

$users = Users::select(['id', 'first_name', 'last_name'])
        ->whereIn('id', $arrayOfIds)
        ->selectSub($firstActivity, 'start_date')
        ->paginate(25);

Вот запрос, когда он выполняется и выдает ошибку:

select 
`id`, 
`first_name`, 
`last_name`, 
    ((select `created_at` 
    from `live_activity` 
    where `user_id` = `id`) 
    union 
    (select `created_at` 
    from `test_activity` 
    where `user_id` = `id`
    limit 1) as `start_date` 
from `users` 
where `id` in (....) 
limit 25 
offset 0)

Я получаю следующую ошибку:

Query 1 ERROR: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'union 

Как я могу сделать эта работа? И есть ли лучший и более эффективный способ выполнить такой запрос с помощью Laravel? Спасибо.

ОБНОВЛЕНИЕ: Я предоставил образцы данных для всех, кто хочет помочь. Вот запрос, который я сейчас пытаюсь выполнить:

select 
id,
first_name,
last_name,
(select created_at 
from test_activity
where user_id = users.id
union 
select created_at
from live_activity
where user_id = users.id
order by created_at asc
limit 1) as start_date
from users;

Как мне преобразовать это в красноречивый?

1 Ответ

0 голосов
/ 05 мая 2020

Во многих случаях соединения выполняются быстрее, чем подзапросы. Я рекомендую работать с sql и протестировать, что быстрее, прежде чем записывать его в Laravel, поскольку вы все равно не используете ORM, а затем просто переписать лучший запрос, используя язык построения запросов.

Подход соединения будет объединять все три столбца, используя join where MAX (created_at) как для testactivity, так и для liveactivity, а затем используя select GREATEST (test_Created_at, live_create_at) в качестве start_date

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...