У вас действительно есть проблема FULL OUTER JOIN
, но, к сожалению, в настоящее время она не поддерживается MySQL.
К счастью для нас, мы можем эмулировать FULL OUTER JOIN
между таблицами A и B с помощью:
- a СЛЕДУЮЩЕЕ ВНЕШНЕЕ СОЕДИНЕНИЕ из таблицы A в таблицу B для перехвата строк в A, которых нет в B, и совпадения строк между A и B
- a ПРАВИЛЬНОЕ ИСКЛЮЧЕНИЕ ПРИСОЕДИНЯЙТЕСЬ от таблицы B к таблице A для отловастроки в B, которых нет в A
Поскольку ваши таблицы различаются по всем полям, кроме ISBN, нам нужно сделать это в два этапа:
- Сначала нам нужно извлечьISBN, которые соответствуют критериям времени истечения
- Затем мы можем получить информацию из обеих таблиц для ранее выбранных ISBN
Вот пример сценария для проверки нашего запроса:
CREATE TABLE sales (
isbn INT NOT NULL
,sale_time TIMESTAMP NOT NULL
,sale_value VARCHAR(100)
,PRIMARY KEY (isbn)
);
CREATE TABLE affiliate_sales (
isbn INT NOT NULL
,sale_time TIMESTAMP NOT NULL
,affiliate_sale_value VARCHAR(100)
,PRIMARY KEY (isbn)
);
INSERT INTO sales (isbn,sale_time,sale_value) VALUES (1,TIMESTAMPADD(HOUR,-30,NOW()),'expired_sale');
INSERT INTO sales (isbn,sale_time,sale_value) VALUES (2,TIMESTAMPADD(HOUR,-34,NOW()),'expired_sale');
INSERT INTO sales (isbn,sale_time,sale_value) VALUES (3,TIMESTAMPADD(HOUR,-23,NOW()),'unexpired_sale');
INSERT INTO sales (isbn,sale_time,sale_value) VALUES (4,TIMESTAMPADD(HOUR,-12,NOW()),'unexpired_sale');
INSERT INTO sales (isbn,sale_time,sale_value) VALUES (5,TIMESTAMPADD(HOUR,-12,NOW()),'unexpired_sale_only');
INSERT INTO affiliate_sales (isbn,sale_time,affiliate_sale_value) VALUES (1,TIMESTAMPADD(HOUR,-74,NOW()),'expired_affiliate_sale');
INSERT INTO affiliate_sales (isbn,sale_time,affiliate_sale_value) VALUES (2,TIMESTAMPADD(HOUR,-54,NOW()),'unexpired_affiliate_sale');
INSERT INTO affiliate_sales (isbn,sale_time,affiliate_sale_value) VALUES (3,TIMESTAMPADD(HOUR,-80,NOW()),'expired_affiliate_sale');
INSERT INTO affiliate_sales (isbn,sale_time,affiliate_sale_value) VALUES (4,TIMESTAMPADD(HOUR,-12,NOW()),'unexpired_affiliate_sale');
INSERT INTO affiliate_sales (isbn,sale_time,affiliate_sale_value) VALUES (6,TIMESTAMPADD(HOUR,-44,NOW()),'unexpired_affiliate_sale_only');
А вот запрос, который извлекает нужные вам данные (извините за неправильное форматирование, я не смог найти, как правильно отобразить их внутри преблока):
SELECT unexpired_sal.isbn
, sal.sale_time, sal.sale_value
, afs.sale_time affiliate_sale_time, afs.affiliate_sale_value
FROM (
SELECT sal.isbn
FROM (
SELECT isbn FROM sales
WHERE TIMESTAMPDIFF(HOUR,sale_time,NOW()) < 24
) sal
LEFT JOIN (
SELECT isbn FROM affiliate_sales
WHERE TIMESTAMPDIFF(HOUR,sale_time,NOW()) < 72
) afs
ON afs.isbn = sal.isbn
UNION ALL
SELECT afs.isbn
FROM (
SELECT isbn FROM sales
WHERE TIMESTAMPDIFF(HOUR,sale_time,NOW()) < 24
) sal
RIGHT JOIN (
SELECT isbn FROM affiliate_sales
WHERE TIMESTAMPDIFF(HOUR,sale_time,NOW()) < 72
) afs
ON afs.isbn = sal.isbn
WHERE sal.isbn IS NULL
) unexpired_sal
LEFT JOIN (
SELECT * FROM sales
WHERE TIMESTAMPDIFF(HOUR,sale_time,NOW()) < 24
) sal
ON sal.isbn = unexpired_sal.isbn
LEFT JOIN (
SELECT * FROM affiliate_sales
WHERE TIMESTAMPDIFF(HOUR,sale_time,NOW()) < 72
) afs
ON afs.isbn = unexpired_sal.isbn
;
Вы получите следующий вывод:
+------+---------------------+---------------------+---------------------+-------------------------------+
| isbn | sale_time | sale_value | affiliate_sale_time | affiliate_sale_value |
+------+---------------------+---------------------+---------------------+-------------------------------+
| 3 | 2010-11-06 11:28:08 | unexpired_sale | NULL | NULL |
| 4 | 2010-11-06 22:28:08 | unexpired_sale | 2010-11-06 22:28:08 | unexpired_affiliate_sale |
| 5 | 2010-11-06 22:28:08 | unexpired_sale_only | NULL | NULL |
| 2 | NULL | NULL | 2010-11-05 04:28:08 | unexpired_affiliate_sale |
| 6 | NULL | NULL | 2010-11-05 14:28:08 | unexpired_affiliate_sale_only |
+------+---------------------+---------------------+---------------------+-------------------------------+
5 rows in set (0.00 sec)