1

単純なクエリであるべきものに苦労しています。

イベント テーブルには、アプリケーション内のユーザー アクティビティが格納されます。クリックするたびに、新しいイベントと日時スタンプが生成されます。最新の日時スタンプを持つ最近アクセスされたレコードのリストを表示する必要があります。過去 7 日間のアクティビティのみを表示する必要があります。

テーブルには、date_event フィールドに対応する自動インクリメント フィールド (eventID) があるため、それを使用してグループ内の最新のレコードを決定することをお勧めします。

予想される最新の日時で、一部のレコードが結果に表示されないことがわかりました。そこで、クエリの基本を取り除きました。

実際のクエリは custID を参照しないことに注意してください。問題を絞り込むためにここに含めます。

        SELECT
            el.eventID,
            el.custID,
            el.date_event
        FROM  
            event_log el
        WHERE 
            el.custID = 12345 AND
            el.userID=987
        GROUP BY  
            el.custID
        HAVING
            MAX( el.eventID )

これが返されます:

eventID     custID  date_event
346290      12345   2013-06-21 09:58:44

ここに説明があります

id  select_type     table   type    possible_keys               key     key_len     ref     rows    Extra
1   SIMPLE          el      ref     userID,custID,Composite     custID  5           const   203     Using where

HAVING MIN を使用するようにクエリを変更しても、結果は変わりません。custID と userID に一致するレコードが多数あるため、別の eventID と date_event が表示されるはずです。

        SELECT
            el.eventID,
            el.custID,
            el.date_event
        FROM  
            event_log el
        WHERE 
            el.custID = 12345 AND
            el.userID=987
        GROUP BY  
            el.custID
        HAVING
            MIN( el.eventID )

前と同じ結果:

eventID     custID  date_event
346290      12345   2013-06-21 09:58:44

変化なし。

これは、別の問題があることを示していますが、それが何であるかはわかりません。

いくつかの指針をいただければ幸いです。

4

2 に答える 2

3
SELECT
    el.eventID,
    el.custID,
    el.date_event
FROM  
    event_log el
WHERE 
    el.custID = 12345 AND
    el.userID=987 AND
    el.eventID IN (SELECT MAX(eventID)
                   FROM event_log
                   WHERE custID = 12345
                   AND userID = 987)

何が機能するかを誤解しているため、クエリは機能しませんHAVING。結果セットの各行で式を評価し、式が true と評価された行を保持します。この式MAX(el.eventID)は、クエリによって選択された最大のイベント ID を返すだけで、現在の行をそのイベント ID と比較しません。

別の方法は次のとおりです。

SELECT
    el.eventID,
    el.custID,
    el.date_event
FROM  
    event_log el
WHERE 
    el.custID = 12345 AND
    el.userID=987
ORDER BY eventID DESC
LIMIT 1

複数の custID で機能するより一般的な形式は次のとおりです。

SELECT el.*
FROM event_log el
JOIN (SELECT custID, max(date_event) maxdate
      FROM event_log
      WHERE userID = 987
      GROUP BY custID) emax
ON el.custID = emax.custID AND el.date_event = emax.maxdate
WHERE el.userID = 987
于 2013-06-28T21:02:06.163 に答える
0

GROUP BY 句を含まないステートメントでグループ関数を使用できますが、それはすべての行でグループ化することと同じです。しかし、あなたは共通の構文を探していると思います。

SELECT
  MIN(el.eventID) AS `min_eventID`, --> Yes it is wrong :(
  el.custID,
  el.date_event
FROM  
  event_log el
WHERE 
  el.userID = 987
GROUP BY el.custID;

しかし、意見の相違は大歓迎です。


[ 編集 ]

私は解決策を十分に迅速に示していないと思います...しかし、おそらくあなたは最速の解決策を探しているのでしょう。
フィールドdate_event のデフォルトが CURRENT_TIMESTAMP であると仮定すると (間違っていますか?)、date_event による順序付けは時間 (およびお金) の無駄になります。
20K 行でいくつかのテストを行いましたが、実行時間は約 5 ミリ秒でした。

SELECT STRAIGHT_JOIN y.*
FROM ((
  SELECT MAX(eventId) as eventId
  FROM event_log
  WHERE userId = 987 AND custId = 12345
)) AS x
INNER JOIN event_log AS y
  USING (eventId);

たぶん (おそらく、誰が知っているか) Straight_join を取得できませんでした。経典に記載されているように、STRAIGHT_JOIN は JOIN と似ていますが、左側のテーブルが常に右側のテーブルの前に読み取られる点が異なります。時々それは役に立ちます。
特定の状況では、テーブル「y」から 99,99% の無駄な行を取得するのではなく、(テーブル「x」で) 前に特定の eventID にフィルター処理する可能性があります。

  • 3、2、... でさらなる不一致が予想されます。
于 2013-06-28T21:02:15.157 に答える