2012-04-28 14 views
2

私は全レコードを取得するようにSQLクエリを持っています。Mysql私は返事で総仕事を続けています

私はこの雇用主によって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() 
+1

このクエリについては、私にはいくつかのことがあります。 1)適切な結合を使用します。暗黙的な結合は問題のトンを引き起こします(私はそれが実際にこれに関係していると考えています)。 2)NOW() - 30日を計算し、その値をj.createdAtと比較する。そうすれば、完全なテーブルスキャン(j.createdAtが索引付けされている場合)を回避できます。 – Corbin

+0

私はまだ30日未満の仕事の完全なリストを取得する必要があります。私は今すぐ計算することによってあなたが意味することを知らないのですか? – Lalajee

+0

NOW()の値は常に変化しているので、MySQLは各行ごとに再計算を比較する必要があります。つまり、DATE_ADDがなくても、フル・テーブル・スキャンが必要になります。基本的には、これは 'a + b Corbin

答えて

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使うには消極的であるいくつかのあいまいな理由のために、あなたがこれを使用する可能性がある場合

は: MySQLは、クエリのこの種のリーディング jobを作ることができないよう

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 
     ) 

、しかし、これは、あまり効率的であるかもしれ。

+0

これは動作します。私は正しい1レコードしか取得していません。 DISPLNCTなしでこれを行うことができます – Lalajee

+1

@Lalajee:あなたは 'DISTINCT 'に対して何を持っていますか?過去に – Quassnoi

+0

がこれを避けるように言われました。 – Lalajee

1

"SELECT count(*)as total"が問題であると思われます。あなたは返されるすべてを数えるようにSQLに依頼しています。それがあなたに返される唯一のものであるため、あなたが「選択」していることに注意してください。

あなたはここで達成しようとしていることを説明していません。 「私はすべての雇用者を獲得する必要がある」というのはあいまいで理解しにくい。あなたは雇用者についてどのようなデータを取得しようとしていますか?彼らのID?彼らの総仕事は?

+0

これは私のページネーションの合計レコードです。現場で仕事をしている雇用者の総数を返すようにシステムに頼む必要があります。 – Lalajee

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の日付に対して一定の式と比較する関数を実行すると、 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人の人が苦労しなくて済むようになりました。

+0

私の日付の値を修正していただきありがとうございます。申し訳ありませんが私の問題は、仕事を掲示した雇用主に番号を返す必要があり、雇用は30日以下です。しかし、私は雇用主のテーブルに1人の雇用者しかいないので、私は60レコードを取得し続けます。 – Lalajee

+0

私はこの雇用者によって掲示される604の仕事があります。 – Lalajee

+0

@Lalajee、私はアナロジーを提供するために私の答えを更新しました。あなたのGROUP句はどこに行きましたか? – Ami

関連する問題