我手上有一个大问题,我有以下SQL结构,其中 contract 表以dinamically方式生成,具有随机名称,例如 _xyz , _xxx 等:
CREATE TABLE contract_xyz(
id INT(11) PRIMARY KEY NOT NULL AUTO_INCREMENT,
created_at DATETIME NOT NULL
);
CREATE TABLE contract_events(
id INT(11) PRIMARY KEY NOT NULL AUTO_INCREMENT,
id_contract INT(11) NOT NULL,
table_contract VARCHAR(255) NOT NULL,
created_at DATETIME NOT NULL
);
INSERT INTO contract_xyz (id,created_at) VALUES (1,'2016-11-01');
INSERT INTO contract_xyz (id,created_at) VALUES (2,'2016-10-21');
INSERT INTO contract_xyz (id,created_at) VALUES (3,'2016-11-04');
INSERT INTO contract_events(id,id_contract,table_contract,created_at) VALUES (1,1,'contract_xyz','2016-11-03');
INSERT INTO contract_events(id,id_contract,table_contract,created_at) VALUES (2,3,'contract_xyz','2016-11-04');
每份合约都有自己的活动。我需要解决以下问题:
获取所有在2天内没有新活动的合同,或者根本没有任何活动,并且是在2天前创建的。
我尝试过 LET JOIN ,但结果并不正确。我得到的最近的是以下查询:
SELECT `contract_xyz`.*
FROM `contract_xyz`
WHERE EXISTS(SELECT 1
FROM `contract_events`
WHERE
`contract_events`.id_contract = `contract_xyz`.id AND `contract_events`.table_contract = 'contract_xyz'
AND DATEDIFF(CURDATE(), `contract_events`.created_at) >= 2
ORDER BY `contract_events`.created_at DESC
LIMIT 1)
OR (NOT EXISTS(SELECT 1
FROM `contract_events`
WHERE `contract_events`.id_contract = `contract_xyz`.id AND
`contract_events`.table_contract = 'contract_xyz') AND
DATEDIFF(CURDATE(), `contract_xyz`.created_at) >= 2);
但我仍然无法找到没有任何事件的合同,并且是在2天前创建的。
答案 0 :(得分:1)
我会创建一个子查询,其中包含每个合约的最大事件日期。我会在这个子查询上加入合约表。您可以根据最大事件日期和创建日期字段进行过滤,以实现预期结果:
select c.*
from contract_xyz c
left join
(select id_contract,
max(created_at) max_event_date
from contract_events
group by id_contract) t on c.id-t.id_contract
where
DATEDIFF(CURDATE(), t.max_event_date) >= 2
or (t.max_event_date is null and DATEDIFF(CURDATE(), c.created_at) >= 2)
或者,您不使用子查询,而是直接使用group by连接2个表,并在having
子句中进行过滤。
答案 1 :(得分:0)
LEFT OUTER JOIN
ON
条件可以在此处提供帮助:
select c.id, c.created_at,count(e.id) as contract_events_less_than_2_days_old
from contract_xyz c
left outer join contract_events e on e.id_contract = c.id
and e.table_contract = 'contract_xyz'
and e.created_at > now() - interval 2 day
where c.created_at < now() - interval 2 day
and e.id is null
group by c.id, c.created_at;
如果您对它有任何控制权,我会建议不要动态生成表名!