1

次のクエリがあります。

SELECT t.ID, t.caseID, time
FROM tbl_test t
INNER JOIN (
    SELECT ID, MAX( TIME ) 
    FROM tbl_test
    WHERE TIME <=1353143351
    GROUP BY caseID 
    ORDER BY caseID DESC -- ERROR HERE!
) s
USING (ID)

ORDER BY内部結合で使用した場合にのみ正しい結果が得られるようです。何故ですか?結合に ID を使用しているため、順序は影響を受けません。order by を削除すると、データベースから古いエントリが取得されます。ID は主キーで、caseID は異なるタイムスタンプを持つ複数のエントリを持つ一種のオブジェクトです。

4

3 に答える 3

4

このクエリはあいまいです:

SELECT ID, MAX( TIME ) 
FROM tbl_test
WHERE TIME <=1353143351
GROUP BY caseID 

MAX(TIME) が発生する行の ID が返されるとは限らないため、あいまいです。の個別の値ごとに MAX(TIME) を返しますがcaseID、他の列 (ID など) の値はグループのメンバーから任意に選択されます。

実際には、MySQL は、格納順に行をスキャンするときに、グループ内で最初に見つかった行を選択します。

例:

caseID  ID  time
  1     10  15:00
  1     12  18:00
  1     14  13:00

最大時間は 18:00 で、これは ID 12 の行です。ただし、クエリは ID 10 を返します。これは、グループ内の最初の行であるためです。ORDER BY で順序を逆にすると、ID 14 が返されます。最大時間が見つかった行ではありませんが、行グループの反対側からのものです。

ORDER BY caseID DESC偶然にも、ID の増加に伴って Time 値が増加するため、クエリが機能します。

この種のクエリは、実際には、標準 SQL および他のほとんどのブランドの SQL データベースではエラーになります。MySQL は、ユーザーが明確なクエリを作成する方法を知っていることを信頼して、それを許可します。

修正は、明確な場合にのみ選択リストの列を使用することです。つまり、列が GROUP BY 句にある場合、各グループは 1 つの異なる値のみを持つことが保証されます。

SELECT caseID, MAX( TIME ) 
FROM tbl_test
WHERE TIME <=1353143351
GROUP BY caseID 
于 2013-03-29T20:09:44.730 に答える
1

caseID ごとに MAX(TIME) を取得しているため、この問題が発生していますが、ID ではなく caseID でグループ化しているため、任意の ID を取得しています。これは、MAX などの集計関数を使用する場合、select 内のグループ化されていないフィールドごとに、集計方法を指定する必要があるためです。つまり、それが SELECT にあり、GROUP BY にない場合、MySQL に集計方法を指示する必要があります。そうしないと、ランダムな行が得られます (まあ、それ自体はランダムではありませんが、必ずしも期待する順序にはなりません)。

ORDER BY が機能している理由は、グループ化の前にクエリ オプティマイザーが結果をソートするようにだますためです。これにより、たまたま必要な結果が生成されますが、常にそうであるとは限りません。

必要なのは、caseID が指定された MAX(TIME) を持つ ID です。つまり、INNER 結合は caseID (ID ではない) と時間 (外部テーブルの 1 行ごとに 1 行を与える) で接続する必要があります。

バーマーは実際のクエリで私を打ち負かしましたが、それがあなたが望む方法です。

于 2013-03-29T20:08:45.417 に答える
1
SELECT t.ID, t.caseID, time
FROM tbl_test t
INNER JOIN (
    SELECT caseID, MAX( TIME ) maxtime
    FROM tbl_test
    WHERE TIME <=1353143351
    GROUP BY caseID
) s
ON t.caseID = s.caseID and t.time = s.maxtime
于 2013-03-29T20:05:47.530 に答える