2

合計レコードを取得したいSQLクエリがあります。

私は 1 つの雇用主と、この雇用主による 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() を (1 回だけ) 評価します。次に、createdAt の各日付に 30 日を追加して、NOW() より大きいかどうかを確認します。MySQL はこれを自動的に最適化する場合があり、バージョンやその他の要因によって異なりますが、一般に、各行の createdAt 日付に対して関数を実行して定数式と比較するのは良くありません。 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 日を差し引いて基準を事前に計算し、単純にその日付より後の誕生日の人がいるかどうかを尋ねます。計算を 1 回行うだけで、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 に答える