Как выбрать одно значение из объединения двух таблиц? - PullRequest
0 голосов
/ 06 мая 2020

Я пытаюсь чего-то добиться в Laravel / MySQL и не могу указать правильное направление для решения. Я могу добиться того, что ищу, с помощью подзапросов, но мне сказали, что они не так эффективны, как соединения. И мне придется преобразовать решение для этого в Eloquent / Query Builder, и то, как я его использую для работы с подзапросами и объединениями, похоже, нелегко преобразовать.

То, что я пытаюсь сделать do - это выбрать одну строку из двух возможных таблиц на основе даты created_at строки. Я хочу объединить это значение created_at с моей таблицей пользователей в виде нового столбца с именем started_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 old_activity (
  id INTEGER,
  user_id INTEGER,
  firm_id INTEGER,
  amount INTEGER,
  created_at DATE
 );

INSERT INTO old_activity (id, user_id, firm_id, amount, created_at)
VALUES 
(1, 1, 3, 5.24, '2019-04-29'), 
(2, 2, 7, 4, '2019-03-28'), 
(3, 3, 4, 6.99, '2019-04-28');

CREATE TABLE new_activity (
  id INTEGER,
  user_id INTEGER,
  firm_id INTEGER,
  plays INTEGER,
  saves INTEGER,
  created_at DATE
);

INSERT INTO new_activity (id, user_id, firm_id, plays, saves, created_at)
VALUES 
(1, 1, 3, 10, 1, '2019-04-27'), 
(2, 2, 3, 12, 2, '2019-03-29'), 
(3, 3, 3, 6, 3, '2019-04-27');

CREATE TABLE firms (
  id INTEGER,
  name TEXT
);

INSERT INTO firms (id, name)
VALUES 
(1, 'apple'), 
(2, 'banana'), 
(3, 'orange');
select 
id,
first_name,
last_name,
(select created_at from old_activity 
 where user_id = users.id
 union
 select created_at from new_activity 
 where user_id = users.id
 order by created_at asc 
 limit 1) as started_at
from users

Запрос должен возвращать только самые старые created_at для конкретного пользователя в одной из двух таблиц activity.

Как я могу добиться этого с помощью соединения? Любая помощь в этом будет принята с благодарностью.

1 Ответ

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

Хммм. . . Вы всегда можете использовать оконные функции:

select u.*, a.*
from users u left join
     (select a.*,
             row_number() over (partition by a.user_id order by a.created_at desc) as seqnum
      from ((select oa.* from old_activity oa) union all
            (select na.* from new_activity na)
           ) a
     ) a
     on a.user_id = a.id and a.seqnum = 1
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...