7

私はここで同様のタイプの質問を見ましたが、それらのどれも私の状況を助けませんでした。

テストと言うテーブルがあります(mysql MyISAMを使用)

テストには次のスキーマがあります。

    TID INT PRIMARY KEY AUTO_INCREMENT
    TData varchar (data that i want to select)
    TUserID INT (this will be joined with users table, same users can have many records here)
    TViewedAt DATETIME (records each time user visits page, datetime format)

これで、現在ログインしているユーザーがテストページにアクセスするたびに、アクセスしたユーザーIDを記録するレコードがこのテーブルに追加され、ユーザーがアクセスしたデータと日時がTIDで毎回自動的にインクリメントされます。

次に、バックエンド管理ページがあり、どのユーザーがテストページにアクセスしたか、何回、データをいつ表示したかを確認できます。基本的に、最新の20〜25行のリストを含むテーブルです。私のクエリは、データごとに1つのレコードのみを選択する必要があります。ユーザーのデータは同じでも時間は異なりますが、ユーザーごとに最新のデータを1つだけ選択したいと思います。したがって、ユーザーがテストページに10回アクセスした場合、10個のレコードがデータベースに送信されますが、テーブルには最新の1個のレコードしか表示されません。別のユーザーがページに15回アクセスすると、この2番目のユーザーの1つのレコードが再び表示されるため、合計で2つの行がテーブルに表示されます。すべてが機能するようになりましたが、何らかの理由でGROUP BYが実行され、MAX(date)によって各日付の最新の日時が表示されません。

これが私の質問です:

   SELECT *
   FROM Test
   WHERE TUserID = 123
   GROUP BY TData
   ORDER BY TViewedAt

2行を返しますが、そのうち最新の行はありません。

どうもありがとう

4

4 に答える 4

15

以下で必要なことを達成できると思います。これらの操作はいわゆる「グループ単位の最大値」です。

オプション1

これは最も理解しやすい方法です。サブクエリはTIDすべてのユーザーに対して最大値を返します。これは、maxが一緒に使用されGroup By、他のクエリを実行してそれらのIDのすべてのデータを取得するためです。

 Select TID, TData, TUserID, TViewedAt
 From Test 
 Where TID In(
    Select Max(TID)
    From Test
    Group By TUserID
)

オプション2

理解するのは少し複雑ですが、おそらくより効率的です。これt1.TViewedAtは、が最大値の場合、t2.TViewedAtそれより大きい値はなく、t2行の値はになるということに基づいて機能しますNULL

SELECT t1.TID, t1.TData, t1.TUserID, t1.TViewedAt
FROM Test t1
LEFT JOIN Test t2 ON t1.TUserID = t2.TUserID AND t1.TViewedAt < t2.TViewedAt
WHERE t2.TUserID IS NULL;

結果

TID TData   TUserID   TViewedAt
4   test3   123       2012-10-05 00:00:00.000
5   test2   213       2012-10-03 00:00:00.000
于 2012-10-05T19:05:30.710 に答える
1

あなたGROUP BY TUserIDは最大骨材のためにする必要があります。

SELECT
  TID,
  TData,
  main.TUserID
  main.TViewedAt
FROM
  yourTable main
  JOIN ( 
    SELECT TUserID, MAX(TViewedAt) AS TViewedAT FROM yourTable GROUP BY TUserID
  ) tmax ON main.TUserID = tmax.TUserID AND main.TViewedAt = tmax.TViewedAt

これは、サブクエリに対して結合する移植可能なメソッドです。サブクエリはTUserID,TViewedAtユーザーごとに最新のものをプルし、それはメインテーブルに対して結合されてTData、一致するものをプルします。

一度に1人のユーザーのみが必要な場合は、次のことができます。

SELECT 
  TData,
  TViewedAt
FROM yourTable
WHERE TUserID = 'someid'
GROUP BY TUserId
HAVING TViewedAt = MAX(TViewedAt)

上記は、MySQLで私が書いた方法でのみ機能します。他のRDBMSは、リストにはTData表示されているが、には表示されていないという事実について文句を言います。SELECTGROUP BY

于 2012-10-05T18:59:56.967 に答える
1

次のクエリは、あなたを助けるかもしれません-

select * from pages where date(create_date)=(select date(create_date) from pages order by create_date limit 1)
于 2014-03-28T13:53:54.510 に答える
0
SELECT t1.TData, t1.TUserID, t1.TViewedAt 
FROM Test t1
JOIN
(SELECT TUserID, MAX(TViewedAt)
FROM Test
GROUP BY TUserID) t2
ON t1.TUserID = t2.TUserID AND t1.TViewedAt=t2.TViewedAt
于 2012-10-05T19:01:28.747 に答える