您的查詢應該爲所有僱主返回所有工作的計數,但有一些標準必須匹配才能顯示。如你所使用的,一個隱式連接是一個INNER JOIN。這要求所有標準匹配才能包含行。這意味着它只返回「isActive」,「beenActive」,「status = 1」,以及createdAt過去少於30天的職位,其中employeres是「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-28 10:59:48
Ami
有些東西會跳出我對這個查詢。 1)使用適當的連接。隱式連接導致大量問題(我懷疑它實際上涉及到這一點)。 2)預先計算NOW() - 30天,然後使用該值與j.createdAt進行比較。這樣,您可以避免全表掃描(如果j.createdAt被索引)。 – Corbin 2012-04-28 10:16:05
我需要獲得仍然少於30天的完整工作清單。我不知道Precalculate NOW()是什麼意思? – Lalajee 2012-04-28 10:18:57
由於NOW()的值不斷變化,因此MySQL必須爲每一行重新計算它的值。這意味着即使沒有DATE_ADD,也需要全表掃描。基本上,你有這個:'a + b
Corbin
2012-04-28 10:21:20