您的查询应该返回所有雇主的所有工作的计数,但有一些标准必须匹配才能显示。正如您所使用的,隐式连接是 INNER JOIN。这要求所有条件都匹配才能包含行。这意味着它只返回“isActive”、“beenActive”、“status=1”和 createdAt 是过去 30 天以内的工作,其中雇主为“isActive”和“status=1”。检查您的数据,看看这是否是您想要的。
SELECT c.id AS employerID, count(*) as total
FROM employer as c, job as j
WHERE c.isActive=1 AND c.status=1
AND j.employerIDFK = c.id
AND j.isActive=1
AND j.beenActive=1
AND j.status=1
AND DATE_ADD( j.createdAt, INTERVAL 30 DAY ) > NOW()
GROUP BY c.id
至于其他人试图对 createdAt 上的过滤器说什么,MySQL 将首先评估 NOW()(仅一次)。然后它将每个 createdAt 日期添加 30 天,以查看它是否大于 NOW()。MySQL 有时会自动优化这一点,这取决于您的版本和其他一些因素,但一般来说,针对每行的 createdAt 日期执行一个函数以将其与常量表达式进行比较是不好的,因为 MySQL 无法在createdAt 列。
所以,你应该转换:
AND DATE_ADD( j.createdAt, INTERVAL 30 DAY ) > NOW()
对此:
AND j.createdAt > DATE_ADD( NOW(), INTERVAL -30 DAY )
这将 j.createdAt 列保留为普通列,因此 MySQL 现在可以利用该列的任何索引来查找过去不到 30 天的日期。
这相当于站在一个有 100 人的房间里,要求他们将生日加 30 天,然后问谁计算的日期比今天大。你刚刚让 100 人工作。相反,通过从今天的日期减去 30 天来预先计算标准,并简单地询问是否有人的生日大于该日期。你只需要做一次计算,就可以让这 100 个人免于繁重的工作。