我有两个表,在此示例中称为表a
和表b
。现在,如果表a
中没有匹配项,或者表b
中的记录已过期,我想从表b
中选择所有内容。
我在考虑在表LEFT JOIN
和b
上使用b.key IS NULL
。这将为我提供表a
中的所有记录,并且不匹配表a
。
SELECT a.id, a.title
FROM a
LEFT JOIN b ON a.id = b.a_id
WHERE b.id IS NULL
但我正在努力应对过期的部分(3天过期)。我试着像这样放入JOIN部分:
SELECT a.id, a.title
FROM a
LEFT JOIN b ON a.id = b.a_id AND b.created_at <= DATE_SUB(NOW(), INTERVAL 3 DAY)
WHERE b.id IS NULL
但这给了我没有过期的项目,而不是过期的项目。
下一个问题是,表b将有多个匹配项。这意味着它可以多次旧a_id,但所有时间戳都不同。在查询过期记录时,我只对表b
的最新记录感兴趣。
Product 3
表a
CREATE TABLE `a` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`title` varchar(25) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
表b
CREATE TABLE `b` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`a_id` int(11) DEFAULT NULL,
`created_at` datetime DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
数据
INSERT INTO `a` (`id`, `title`)
VALUES
(1, 'Product 1'),
(2, 'Product 2'),
(3, 'Product 3');
INSERT INTO `b` (`id`, `a_id`, `created_at`)
VALUES
(1, 1, '2017-08-20 12:30:32'),
(2, 2, '2017-08-24 12:30:39');
(3, 1, '2017-08-24 13:19:13');
答案 0 :(得分:1)
您可以使用EXISTS
子句:
SELECT a.id, a.title
FROM a
WHERE
NOT EXISTS (SELECT 1 FROM b WHERE a.id=b.a_id) OR (
(SELECT b.created_at FROM b WHERE a.id=b.a_id
ORDER BY b.created_at DESC LIMIT 1) <= DATE_SUB(NOW(), INTERVAL 3 DAY))
答案 1 :(得分:0)
呃,真的,这让你难过吗?b.created_at&lt; = DATE_SUB(NOW(),INTERVAL 3 DAY)
但这给了我没有过期的项目,而不是过期的项目。
b.created_at > DATE_SUB(NOW(), INTERVAL 3 DAY)
我只对表b的最新记录感兴趣
然后用:
替换b(SELECT base.* FROM b base
WHERE NOT EXISTS (
SELECT 1
FROM b prev
WHERE prev.a_id=base.a_id
AND prev.created_at>base.created_at
)
) c
性能不是最佳的(并且至少有3种其他方式来编写查询)但不知道架构的样子和数据分布,我不能告诉你什么是最好的解决方案。
答案 2 :(得分:-2)
使用 LEFT OUTER JOIN而不是LEFT JOIN 即使为null,这也可以在表b上给出结果