2016-06-13 7 views
4

私は2つのテーブル、つまりスタッフとスタッフの試験時間表に参加したいと考えています。スタッフはN回の試験に参加できます。私の結果は、スタッフID、スタッフ名、最後に完了した試験の終了時刻でなければなりません。SQLクエリが正常に動作しない

私のテーブルの構造は以下で

スタッフテーブル

結果セットの
staff_id staff_full_name  staff_status 

    500  Sakthi   active 

    550  Siraj   active 

    600  Shihab K H  active 

    620  John David  active 

    670  Javed Akthar  active 

examtimeテーブル

examtime_id examtime_staffid examtime_endtime 

    100  500   2014-10-10 

    101  600   2016-05-01 

    102  670   2016-06-10 

    103  670   2014-04-01 

    104  670   2016-06-13 

    105  670   2016-06-11 

SQLクエリは、以下の

SELECT S.staff_id, S.staff_full_name, ET.examtime_endtime 
FROM staffs S LEFT JOIN examtime ET ON ET.examtime_staffid = S.staff_id 
WHERE 1 AND S.staff_status = 'active' GROUP BY S.staff_full_name ORDER BY S.staff_full_name ASC , ET.examtime_endtime DESC 

ですが、私はGEです結果セットを以下のように設定します。試験の終了時刻にかかわらず、試験時間表の最初のレコードをフェッチしています。結果セット(Javed Akthar最新試験日は2016-06-13ですが、2016-06-10を取得しています)。

500 Sakthi  2014-10-10 

600 Shihab KH 2016-05-01 

670 Javed Akthar 2016-06-10 
+2

あなたはそれが意味するようにしたいので、あなたの 'GROUP BY'」は、問題を引き起こしている:集計に含まれていないとGROUP BYではなく、MySQLはその列の任意の値を選択した列)を持つことができます実際には[それをしない](https://dev.mysql.com/doc/refman/5.7/en/group-by-handling.html): "...私の心を読んでください"この場合、サーバは各グループから任意の値を自由に選ぶことができるので、同じでなければ選択された値は不確定で、おそらくあなたが望むものではありません。 –

答えて

2

問題があなたのGROUP BY句である、あなたはそれぞれのために日付を指定していないので、ランダムに一つを選択され、最大のものをnecessarlyありません。

You can find a good explanation about this behaviour here in @mjv answer

この文字列で検索してください:

SELECT S.staff_id, S.staff_full_name, max(ET.examtime_endtime) as max_endTime 
FROM staffs S 
LEFT JOIN examtime ET 
ON (ET.examtime_staffid = S.staff_id) 
WHERE S.staff_status = 'active' 
GROUP BY S.staff_id , 
     S.staff_full_name 
ORDER BY S.staff_full_name ASC , 
     max_endTime DESC 

それは各staff_idの最大の日付を選択し、それによって注文されます。一般的には、GROUP BY句の各グループ(この場合はstaff_id,staff_full_name)と、集計関数(AVG/MAX/MIN ..)を持つ他のすべての列を表すすべての列を指定するのが一般的です。未来。

1

各スタッフの最新の試験時間が必要なだけで、そのテーブルの他の列は必要ない場合は、標準SQLでこれを行うことができ、導入した危険性を避けるためにMySQL "extension"

SELECT MIN(S.staff_id) as staff_id, 
     S.staff_full_name, 
     MAX(ET.examtime_endtime) as examtime_endtime 
FROM staffs S LEFT JOIN examtime ET ON ET.examtime_staffid = S.staff_id 
WHERE S.staff_status = 'active' 
GROUP BY S.staff_full_name 
+0

実際、 'staff_id'はユニークなので、' MIN() 'の必要はありません。 – sagi

+0

@sagi - 標準であるためには、GROUP BYまたは集約のいずれかになければなりません。それがユニークだとわかっているので、私たちがどちらを使うかは問題ではありません。私は 'GROUP'キーのサイズを最小限にすることを好みますが、あなたは不要な集約を排除することを好むでしょう。どのアプローチが正しいかは、いくつかの要因に依存する可能性があります(上記では標準SQLを使用しているため)、プラットフォーム/バージョンによってプラットフォームのトレードオフが異なる場合があります。 –

関連する問題