2

我有 sql 查询,我想在其中获取总记录。

我有一个雇主和这个雇主的 600 个工作。

我需要获取所有雇主,但由于某种原因,我的查询返回了雇主发布的总职位。

请让我知道我在此查询中出了什么问题。

SELECT count(c.id) as total 
FROM employer as c INNER JOIN  job as j ON j.employerIDFK = c.id 
WHERE c.isActive=1 AND c.status=1 
AND j.isActive=1 
AND j.beenActive=1 
AND j.status=1 
AND DATE_ADD( j.createdAt, INTERVAL 30 DAY ) > NOW()
4

3 回答 3

2

您的查询应该返回所有雇主的所有工作的计数,但有一些标准必须匹配才能显示。正如您所使用的,隐式连接是 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 个人免于繁重的工作。

于 2012-04-28T10:59:48.553 回答
2
SELECT  COUNT(DISTINCT c.id) AS total 
FROM    employer c
JOIN    job j
ON      j.employerIDFK = c.id
WHERE   c.isActive = 1
        AND c.status = 1
        AND j.isActive = 1 
        AND j.beenActive = 1 
        AND j.status = 1 
        AND j.createdAt >= NOW() - INTERVAL 30 DAY

创建以下索引:

employer (isActive, status)
job (employerFKID)
job (isActive, beenActive, status, createdAt, employerFKID)

以便查询更快地工作。

如果由于某些晦涩的原因你不愿意使用DISTINCT,你可以使用这个:

SELECT  COUNT(c.id) AS total
FROM    employer c
WHERE   c.isActive = 1
        AND c.status = 1
        AND c.id IN
        (
        SELECT  employerIDFK
        FROM    job j
        WHERE   j.isActive = 1
                AND j.beenActive = 1
                AND j.status = 1
                AND j.createdAt >= NOW() - INTERVAL 30 DAY
        )

,但是,这可能效率较低,因为MySQL无法job在此类查询中领先。

于 2012-04-28T11:30:41.000 回答
1

我怀疑“SELECT count(*) as total”是你的问题。您要求 SQL 计算返回的所有内容。注意你正在“选择”的东西,因为这是唯一会返回给你的东西。

您没有完全解释您要在这里实现的目标。“我需要找到所有的雇主”是含糊不清的,很难理解。您想获取有关雇主的哪些数据?他们的身份证?他们的总工作量?

于 2012-04-28T10:20:02.930 回答