863

私のテーブルは次のとおりです。

ID 日付時刻 プレーヤー 資源
1 10 2009/04/03 ジョン 399
2 11 2009/04/03 ジュリエット 244
5 12 2009/04/03 ボラット 555
3 10 2009/03/03 ジョン 300
4 11 2009/03/03 ジュリエット 200
6 12 2009/03/03 ボラット 500
7 13 2008/12/24 ボラット 600
8 13 2009/01/01 ボラット 700

homeの最大値を保持するそれぞれの個別を選択する必要がありますdatetime

結果は次のようになります。

ID 日付時刻 プレーヤー 資源
1 10 2009/04/03 ジョン 399
2 11 2009/04/03 ジュリエット 244
5 12 2009/04/03 ボラット 555
8 13 2009/01/01 ボラット 700

私が試してみました:

-- 1 ..by the MySQL manual: 

SELECT DISTINCT
  home,
  id,
  datetime AS dt,
  player,
  resource
FROM topten t1
WHERE datetime = (SELECT
  MAX(t2.datetime)
FROM topten t2
GROUP BY home)
GROUP BY datetime
ORDER BY datetime DESC

うまくいきません。データベースは 187 行を保持していますが、結果セットには 130 行あります。結果には の重複がいくつか含まれていますhome

-- 2 ..join

SELECT
  s1.id,
  s1.home,
  s1.datetime,
  s1.player,
  s1.resource
FROM topten s1
JOIN (SELECT
  id,
  MAX(datetime) AS dt
FROM topten
GROUP BY id) AS s2
  ON s1.id = s2.id
ORDER BY datetime 

いいえ。すべてのレコードを提供します。

-- 3 ..something exotic: 

色々な結果で。

4

21 に答える 21

80

T-SQLバージョンは次のとおりです。

-- Test data
DECLARE @TestTable TABLE (id INT, home INT, date DATETIME, 
  player VARCHAR(20), resource INT)
INSERT INTO @TestTable
SELECT 1, 10, '2009-03-04', 'john', 399 UNION
SELECT 2, 11, '2009-03-04', 'juliet', 244 UNION
SELECT 5, 12, '2009-03-04', 'borat', 555 UNION
SELECT 3, 10, '2009-03-03', 'john', 300 UNION
SELECT 4, 11, '2009-03-03', 'juliet', 200 UNION
SELECT 6, 12, '2009-03-03', 'borat', 500 UNION
SELECT 7, 13, '2008-12-24', 'borat', 600 UNION
SELECT 8, 13, '2009-01-01', 'borat', 700

-- Answer
SELECT id, home, date, player, resource 
FROM (SELECT id, home, date, player, resource, 
    RANK() OVER (PARTITION BY home ORDER BY date DESC) N
    FROM @TestTable
)M WHERE N = 1

-- and if you really want only home with max date
SELECT T.id, T.home, T.date, T.player, T.resource 
    FROM @TestTable T
INNER JOIN 
(   SELECT TI.id, TI.home, TI.date, 
        RANK() OVER (PARTITION BY TI.home ORDER BY TI.date) N
    FROM @TestTable TI
    WHERE TI.date IN (SELECT MAX(TM.date) FROM @TestTable TM)
)TJ ON TJ.N = 1 AND T.id = TJ.id

EDIT
残念ながら、MySQL には RANK() OVER 関数はありません。
ただし、エミュレートすることはできます。MySQL を使用した分析 (AKA ランキング) 関数のエミュレートを参照してください。
これはMySQLのバージョンです:

SELECT id, home, date, player, resource 
FROM TestTable AS t1 
WHERE 
    (SELECT COUNT(*) 
            FROM TestTable AS t2 
            WHERE t2.home = t1.home AND t2.date > t1.date
    ) = 0
于 2009-03-04T20:59:52.580 に答える
30

homeこれは、それぞれに等しいDATETIME'sを持つ 2 つ以上の行がある場合でも機能します。

SELECT id, home, datetime, player, resource
FROM   (
       SELECT (
              SELECT  id
              FROM    topten ti
              WHERE   ti.home = t1.home
              ORDER BY
                      ti.datetime DESC
              LIMIT 1
              ) lid
       FROM   (
              SELECT  DISTINCT home
              FROM    topten
              ) t1
       ) ro, topten t2
WHERE  t2.id = ro.lid
于 2009-03-04T20:24:20.747 に答える
22

私はこれがあなたに望ましい結果を与えると思います:

SELECT   home, MAX(datetime)
FROM     my_table
GROUP BY home

ただし、他の列も必要な場合は、元のテーブルと結合するだけです(Michael La Voie回答を確認してください)

よろしくお願いします。

于 2009-03-04T20:30:58.797 に答える
17

人々はこのスレッドに出くわし続けているように見えるので (コメントの日付は 1.5 年から)、それほど単純ではありません:

SELECT * FROM (SELECT * FROM topten ORDER BY datetime DESC) tmp GROUP BY home

集計関数は必要ありません...

乾杯。

于 2010-12-05T17:04:14.373 に答える
11

これを試すこともできます。大きなテーブルの場合、クエリのパフォーマンスが向上します。各家のレコードが 2 つ以下で、日付が異なる場合に機能します。より優れた一般的な MySQL クエリは、上記の Michael La Voie によるものです。

SELECT t1.id, t1.home, t1.date, t1.player, t1.resource
FROM   t_scores_1 t1 
INNER JOIN t_scores_1 t2
   ON t1.home = t2.home
WHERE t1.date > t2.date

または、Postgres または分析関数を提供するデータベースの場合は、

SELECT t.* FROM 
(SELECT t1.id, t1.home, t1.date, t1.player, t1.resource
  , row_number() over (partition by t1.home order by t1.date desc) rw
 FROM   topten t1 
 INNER JOIN topten t2
   ON t1.home = t2.home
 WHERE t1.date > t2.date 
) t
WHERE t.rw = 1
于 2010-02-16T20:51:50.110 に答える
9
SELECT  tt.*
FROM    TestTable tt 
INNER JOIN 
        (
        SELECT  coord, MAX(datetime) AS MaxDateTime 
        FROM    rapsa 
        GROUP BY
                krd 
        ) groupedtt
ON      tt.coord = groupedtt.coord
        AND tt.datetime = groupedtt.MaxDateTime
于 2009-03-04T20:58:54.470 に答える
8

これはOracleで機能します。

with table_max as(
  select id
       , home
       , datetime
       , player
       , resource
       , max(home) over (partition by home) maxhome
    from table  
)
select id
     , home
     , datetime
     , player
     , resource
  from table_max
 where home = maxhome
于 2009-03-05T23:19:39.977 に答える
8

SQL Serverでこれを試してください:

WITH cte AS (
   SELECT home, MAX(year) AS year FROM Table1 GROUP BY home
)
SELECT * FROM Table1 a INNER JOIN cte ON a.home = cte.home AND a.year = cte.year
于 2014-01-17T12:11:29.883 に答える
5
SELECT c1, c2, c3, c4, c5 FROM table1 WHERE c3 = (select max(c3) from table)

SELECT * FROM table1 WHERE c3 = (select max(c3) from table1)
于 2012-07-12T16:11:16.000 に答える
5

基本的にグループごとに各行のランクを計算し、ランク = 1 のように最新の行を除外するサブクエリを使用して、グループごとに最新の行を取得する別の方法

select a.*
from topten a
where (
  select count(*)
  from topten b
  where a.home = b.home
  and a.`datetime` < b.`datetime`
) +1 = 1

デモ

理解を深めるために、各行のランク番号の視覚的なデモを次に示します

いくつかのコメントを読んで、同じ 'home' フィールドと 'datetime' フィールド値を持つ 2 つの行がある場合はどうでしょうか?

上記のクエリは失敗し、上記の状況では複数の行が返されます。この状況を隠蔽するには、上記の状況に該当する行を取得する必要があるかを決定する別の基準/パラメーター/列が必要になります。idサンプルデータセットを表示することにより、自動インクリメントに設定する必要がある主キー列があると想定します。CASEしたがって、この列を使用して、次のようなステートメントを使用して同じクエリを微調整することにより、最新の行を選択できます

select a.*
from topten a
where (
  select count(*)
  from topten b
  where a.home = b.home
  and  case 
       when a.`datetime` = b.`datetime`
       then a.id < b.id
       else a.`datetime` < b.`datetime`
       end
) + 1 = 1

デモ

datetime上記のクエリは、同じ値の中で最大の ID を持つ行を選択します

各行のランク番号のビジュアル デモ

于 2017-11-05T13:35:40.160 に答える
3

使用しない理由: SELECT home, MAX(datetime) AS MaxDateTime,player,resource FROM topten GROUP BY home

于 2015-10-03T10:20:10.213 に答える
1

これを試して

select * from mytable a join
(select home, max(datetime) datetime
from mytable
group by home) b
 on a.home = b.home and a.datetime = b.datetime

よろしくK

于 2009-03-04T20:41:52.407 に答える