Làm cách nào tôi có thể CHỌN các hàng với MAX (Giá trị cột), DISTINCT bằng một cột khác trong SQL?


768

Bảng của tôi là:

id  home  datetime     player   resource
---|-----|------------|--------|---------
1  | 10  | 04/03/2009 | john   | 399 
2  | 11  | 04/03/2009 | juliet | 244
5  | 12  | 04/03/2009 | borat  | 555
3  | 10  | 03/03/2009 | john   | 300
4  | 11  | 03/03/2009 | juliet | 200
6  | 12  | 03/03/2009 | borat  | 500
7  | 13  | 24/12/2008 | borat  | 600
8  | 13  | 01/01/2009 | borat  | 700

Tôi cần phải chọn mỗi khác biệt homegiữ giá trị tối đa của datetime.

Kết quả sẽ là:

id  home  datetime     player   resource 
---|-----|------------|--------|---------
1  | 10  | 04/03/2009 | john   | 399
2  | 11  | 04/03/2009 | juliet | 244
5  | 12  | 04/03/2009 | borat  | 555
8  | 13  | 01/01/2009 | borat  | 700

Tôi đã thử:

-- 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

Không hoạt động. Tập kết quả có 130 hàng mặc dù cơ sở dữ liệu chứa 187. Kết quả bao gồm một số bản sao của 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 

Không. Cung cấp tất cả các hồ sơ.

-- 3 ..something exotic: 

Với kết quả khác nhau.

Câu trả lời:


939

Bạn thật gần gũi! Tất cả những gì bạn cần làm là chọn CẢ HAI nhà và thời gian ngày tối đa của nó, sau đó tham gia trở lại toptenbảng trên các trường CẢ:

SELECT tt.*
FROM topten tt
INNER JOIN
    (SELECT home, MAX(datetime) AS MaxDateTime
    FROM topten
    GROUP BY home) groupedtt 
ON tt.home = groupedtt.home 
AND tt.datetime = groupedtt.MaxDateTime

5
Hãy kiểm tra xem có khác biệt không, nếu hai thời gian tối đa bằng nhau ở cùng một nhà (với những người chơi khác nhau)
Maksym Gontar

5
Tôi nghĩ rằng cách cổ điển để thực hiện điều này là với một phép nối tự nhiên: "CHỌN tt. * TỪ topten tt THAM GIA TỰ NHIÊN (CHỌN nhà, MAX (datetime) NHƯ datetime TỪ topten GROUP BY home) đáng chú ý nhất;" Cùng một truy vấn chính xác, nhưng có thể dễ đọc hơn
Parker

32
Nếu có hai hàng có cùng giá trị trường 'home' và 'datetime' thì sao?
Kemal Duran

3
@Young vấn đề với truy vấn của bạn là nó có thể quay trở lại id, playerresourcecủa hàng không tối đa cho một ví dụ về nhà đưa ra cho nhà = 10 bạn có thể nhận được: 3 | 10 | 04/03/2009 | john | 300 Nói cách khác, nó không đảm bảo rằng tất cả các cột của một hàng trong resultset sẽ thuộc tối đa (datetime) cho nhà nhất định.
sactiw

1
@ me1111 vấn đề với truy vấn của bạn là nó có thể / không thể trả về hàng ith max (datetime) cho một ngôi nhà nhất định. Lý do là GROUP BY sẽ lấy bất kỳ hàng ngẫu nhiên nào cho mỗi nhà và ORDER BY sẽ chỉ sắp xếp toàn bộ kết quả như được tạo bởi GROUP BY
sactiw

87

MySQLGiải pháp nhanh nhất , không có truy vấn bên trong và không có GROUP BY:

SELECT m.*                    -- get the row that contains the max value
FROM topten m                 -- "m" from "max"
    LEFT JOIN topten b        -- "b" from "bigger"
        ON m.home = b.home    -- match "max" row with "bigger" row by `home`
        AND m.datetime < b.datetime           -- want "bigger" than "max"
WHERE b.datetime IS NULL      -- keep only if there is no bigger than max

Giải thích :

Tham gia bảng với chính nó bằng cách sử dụng homecột. Việc sử dụng LEFT JOINđảm bảo tất cả các hàng từ bảng mxuất hiện trong tập kết quả. Những người không có trận đấu trong bảng bsẽ có NULLs cho các cột của b.

Điều kiện khác trên các JOINyêu cầu chỉ khớp với các hàng từ bđó có giá trị lớn hơn trên datetimecột so với hàng từ m.

Sử dụng dữ liệu được đăng trong câu hỏi, LEFT JOINsẽ tạo ra cặp này:

+------------------------------------------+--------------------------------+
|              the row from `m`            |    the matching row from `b`   |
|------------------------------------------|--------------------------------|
| id  home  datetime     player   resource | id    home   datetime      ... |
|----|-----|------------|--------|---------|------|------|------------|-----|
| 1  | 10  | 04/03/2009 | john   | 399     | NULL | NULL | NULL       | ... | *
| 2  | 11  | 04/03/2009 | juliet | 244     | NULL | NULL | NULL       | ... | *
| 5  | 12  | 04/03/2009 | borat  | 555     | NULL | NULL | NULL       | ... | *
| 3  | 10  | 03/03/2009 | john   | 300     | 1    | 10   | 04/03/2009 | ... |
| 4  | 11  | 03/03/2009 | juliet | 200     | 2    | 11   | 04/03/2009 | ... |
| 6  | 12  | 03/03/2009 | borat  | 500     | 5    | 12   | 04/03/2009 | ... |
| 7  | 13  | 24/12/2008 | borat  | 600     | 8    | 13   | 01/01/2009 | ... |
| 8  | 13  | 01/01/2009 | borat  | 700     | NULL | NULL | NULL       | ... | *
+------------------------------------------+--------------------------------+

Cuối cùng, WHEREmệnh đề chỉ giữ các cặp có NULLs trong các cột của b(chúng được đánh dấu *trong bảng trên); điều này có nghĩa, do điều kiện thứ hai từ JOINmệnh đề, hàng được chọn từ mcó giá trị lớn nhất trong cột datetime.

Đọc các Antipotype của SQL: Tránh các cạm bẫy của cuốn sách Lập trình cơ sở dữ liệu cho các mẹo SQL khác.


Với SQLite, phiên bản đầu tiên chậm hơn nhiều so với phiên bản La Voie khi không có chỉ mục trên cột phù hợp (nghĩa là "nhà"). (Đã thử nghiệm với 24k hàng dẫn đến 13k hàng)
Thomas Tempelmann

10
Đây là câu trả lời tốt nhất, nếu bạn hiển thị kế hoạch thực hiện, bạn sẽ thấy ít hơn một bước với truy vấn này
TlmaK0

Điều gì sẽ xảy ra nếu 2 hàng có cùng homedatetimedatetimetối đa là cụ thể home?
Istiaque Ahmed

Cả hai hàng xuất hiện trong tập kết quả. Câu trả lời này là một bằng chứng về khái niệm. Trong mã thực của bạn, bạn có thể có một tiêu chí khác để chỉ chọn một trong số chúng trong tình huống này (có thể là tiêu chí đầu tiên hoặc cuối cùng hoặc bạn sử dụng một cột khác để quyết định). Chỉ cần thêm tiêu chí này như một điều kiện mới trong ONmệnh đề. Fe ... ON ... AND m.id < b.idđể giữ mục nhập gần đây nhất (mục idcó giá trị lớn nhất ) khi hai hàng có cùng giá trị trong homedatetimecột và đó là giá trị tối đa datetime.
axiac

Những chỉ mục nào sẽ tối ưu hóa tốt nhất cho một truy vấn như thế này?
AjaxLeung

73

Đây phiên bản 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
Thật không may, không có hàm RANK () OVER trong MySQL.
Nhưng nó có thể được mô phỏng, xem Hàm mô phỏng phân tích (Xếp hạng AKA) với MySQL .
Vì vậy, đây là phiên bản 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

xin lỗi anh bạn, # 1064 - Bạn có lỗi trong cú pháp SQL của mình; kiểm tra hướng dẫn tương ứng với phiên bản máy chủ MySQL của bạn để biết cú pháp phù hợp để sử dụng gần '() QUÁ (THAM GIA BỞI ĐẶT HÀNG theo thứ tự DESC ban ngày) N TỪ @rapsa) M WHERE N =' tại dòng 1
Kaptah

2
à, vậy là bạn đang sử dụng MySQL. Đó là những gì bạn nên bắt đầu từ! Tôi sẽ cập nhật câu trả lời sớm.
Maksym Gontar

@MaxGontar, đá giải pháp mysql của bạn, thx. Điều gì xảy ra nếu trong @_TestTable của bạn, bạn xóa hàng # 1>: CHỌN 1, 10, '2009-03-04', 'john', 399, đây là gì, nếu bạn có một hàng cho một giá trị nhà cụ thể thì sao? cám ơn.
egidiocs

2
LGI: Thay thế "RANK ()" bằng "ROW_NUMBER ()". Nếu bạn có một cà vạt (gây ra bởi một giá trị ngày trùng lặp), bạn sẽ có hai bản ghi với "1" cho N.
MikeTeeVee

29

Điều này sẽ hoạt động ngay cả khi bạn có hai hoặc nhiều hàng cho mỗi hàng homebằng nhau DATETIME:

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

thêm trường nắp trong bảng, Không tốt
Kaptah

1
Điều này đã không thực hiện trên PHPMyAdmin. Trang làm mới nhưng không có kết quả cũng không có lỗi ..?
Kaptah

WHERE ti.home = t1.home- bạn có thể giải thích cú pháp?
Istiaque Ahmed

@IstiaqueAhmed: chính xác thì bạn không hiểu gì ở đây? Đó là một truy vấn tương quan và biểu thức bạn đề cập là một điều kiện tương quan.
Quassnoi

@Quassnoi, selectTruy vấn có dòng WHERE ti.home = t1.home không cần FROMmệnh đề xác định t1. Vậy nó được sử dụng như thế nào?
Istiaque Ahmed

26

Tôi nghĩ rằng điều này sẽ cung cấp cho bạn kết quả mong muốn:

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

NHƯNG nếu bạn cũng cần các cột khác, chỉ cần thực hiện nối với bảng gốc (kiểm tra Michael La Voiecâu trả lời)

Trân trọng.


8
Anh ấy cũng cần cột khác.
Quassnoi

4
id, home, datetime, player, resource
Quassnoi

17

Vì mọi người dường như tiếp tục chạy vào chủ đề này (ngày bình luận trong khoảng 1,5 năm) không đơn giản hơn nhiều:

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

Không có chức năng tổng hợp cần thiết ...

Chúc mừng.


6
Điều này dường như không hoạt động. Thông báo lỗi: Cột 'x' không hợp lệ trong danh sách chọn vì nó không được chứa trong hàm tổng hợp hoặc mệnh đề GROUP BY.
Fowl

Điều này chắc chắn sẽ không hoạt động trong SQL Server hoặc Oracle, mặc dù có vẻ như nó có thể hoạt động trong MySQL.
ErikE

Điều này thực sự rất đẹp! Cái này hoạt động ra sao? Bằng cách sử dụng DESC và cột trả về nhóm mặc định? Vậy nếu tôi đổi nó thành ASC datetime, nó sẽ trả về hàng sớm nhất cho mỗi nhà?
wayofthefuture

Thật là tuyệt vời!
Người yêu chó

Điều này không hoạt động nếu bạn có các cột không kết hợp (trong MySQL).
dùng3562927

11

Bạn cũng có thể thử cái này và cho hiệu suất truy vấn bảng lớn sẽ tốt hơn. Nó hoạt động khi không có nhiều hơn hai hồ sơ cho mỗi nhà và ngày của họ là khác nhau. Truy vấn MySQL chung tốt hơn là một từ Michael La Voie ở trên.

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

Hoặc trong trường hợp Postgres hoặc những dbs cung cấp chức năng phân tích, hãy thử

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

Câu trả lời này có đúng không? Tôi đã cố gắng sử dụng nó, nhưng nó không chọn bản ghi có ngày mới nhất cho "nhà", mà chỉ xóa bản ghi có ngày cũ nhất. Dưới đây là một ví dụ: SQLfiddle
marcin93w

1
@kidOfDeath - Cập nhật câu trả lời của tôi với bối cảnh và truy vấn Postgres
Shiva

Với SQLite, phiên bản đầu tiên chậm hơn nhiều so với phiên bản La Voie khi không có chỉ mục trên cột phù hợp (nghĩa là "nhà").
Thomas Tempelmann

8

Điều này hoạt động trên 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

1
Làm thế nào để chọn thời gian tối đa này? anh ta yêu cầu nhóm ở nhà, và chọn thời gian tối đa. Tôi không thấy làm thế nào điều này làm điều đó.
n00b

8
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

8

Hãy thử điều này cho 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

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)

5

Đây là phiên bản MySQL chỉ in một mục trong đó có các bản sao MAX (datetime) trong một nhóm.

Bạn có thể kiểm tra tại đây http://www.sqlfiddle.com/#!2/0a4ae/1

Dữ liệu mẫu

mysql> SELECT * from topten;
+------+------+---------------------+--------+----------+
| id   | home | datetime            | player | resource |
+------+------+---------------------+--------+----------+
|    1 |   10 | 2009-04-03 00:00:00 | john   |      399 |
|    2 |   11 | 2009-04-03 00:00:00 | juliet |      244 |
|    3 |   10 | 2009-03-03 00:00:00 | john   |      300 |
|    4 |   11 | 2009-03-03 00:00:00 | juliet |      200 |
|    5 |   12 | 2009-04-03 00:00:00 | borat  |      555 |
|    6 |   12 | 2009-03-03 00:00:00 | borat  |      500 |
|    7 |   13 | 2008-12-24 00:00:00 | borat  |      600 |
|    8 |   13 | 2009-01-01 00:00:00 | borat  |      700 |
|    9 |   10 | 2009-04-03 00:00:00 | borat  |      700 |
|   10 |   11 | 2009-04-03 00:00:00 | borat  |      700 |
|   12 |   12 | 2009-04-03 00:00:00 | borat  |      700 |
+------+------+---------------------+--------+----------+

Phiên bản MySQL với biến người dùng

SELECT *
FROM (
    SELECT ord.*,
        IF (@prev_home = ord.home, 0, 1) AS is_first_appear,
        @prev_home := ord.home
    FROM (
        SELECT t1.id, t1.home, t1.player, t1.resource
        FROM topten t1
        INNER JOIN (
            SELECT home, MAX(datetime) AS mx_dt
            FROM topten
            GROUP BY home
          ) x ON t1.home = x.home AND t1.datetime = x.mx_dt
        ORDER BY home
    ) ord, (SELECT @prev_home := 0, @seq := 0) init
) y
WHERE is_first_appear = 1;
+------+------+--------+----------+-----------------+------------------------+
| id   | home | player | resource | is_first_appear | @prev_home := ord.home |
+------+------+--------+----------+-----------------+------------------------+
|    9 |   10 | borat  |      700 |               1 |                     10 |
|   10 |   11 | borat  |      700 |               1 |                     11 |
|   12 |   12 | borat  |      700 |               1 |                     12 |
|    8 |   13 | borat  |      700 |               1 |                     13 |
+------+------+--------+----------+-----------------+------------------------+
4 rows in set (0.00 sec)

Ra ngoài câu trả lời được chấp nhận

SELECT tt.*
FROM topten tt
INNER JOIN
    (
    SELECT home, MAX(datetime) AS MaxDateTime
    FROM topten
    GROUP BY home
) groupedtt ON tt.home = groupedtt.home AND tt.datetime = groupedtt.MaxDateTime
+------+------+---------------------+--------+----------+
| id   | home | datetime            | player | resource |
+------+------+---------------------+--------+----------+
|    1 |   10 | 2009-04-03 00:00:00 | john   |      399 |
|    2 |   11 | 2009-04-03 00:00:00 | juliet |      244 |
|    5 |   12 | 2009-04-03 00:00:00 | borat  |      555 |
|    8 |   13 | 2009-01-01 00:00:00 | borat  |      700 |
|    9 |   10 | 2009-04-03 00:00:00 | borat  |      700 |
|   10 |   11 | 2009-04-03 00:00:00 | borat  |      700 |
|   12 |   12 | 2009-04-03 00:00:00 | borat  |      700 |
+------+------+---------------------+--------+----------+
7 rows in set (0.00 sec)

Altho Tôi thích câu trả lời này, vì điều này giúp tôi rất nhiều, tôi phải chỉ ra một lỗ hổng lớn, rằng nó phụ thuộc vào hệ thống mysql đã sử dụng. Về cơ bản, giải pháp này dựa vào mệnh đề ORDER BY trong subselect. MIGHT này, hoặc MIGHT KHÔNG hoạt động trong môi trường mysql khác nhau. Tôi đã không thử nó trên MySQL thuần túy, nhưng chắc chắn điều này không hoạt động ĐÁNG TIN CẬY trên MariaDB 10.1, như đã giải thích ở đây stackoverflow.com/questions/26372511/ nhưng nhưng cùng một mã hoạt động tốt trên Percona Server. Nói chính xác, bạn MIGHT, hoặc MIGHT KHÔNG nhận được kết quả tương tự, tùy thuộc vào số lượng cột t1.
Radek

Ví dụ cho tuyên bố này là, trên MariaDB 10.1, nó hoạt động khi tôi sử dụng 5 cột từ bảng t1. Ngay khi tôi thêm cột thứ sáu, rõ ràng là đang rối tung với cách sắp xếp dữ liệu "tự nhiên" trong bảng gốc, nó đã ngừng hoạt động. Lý do là, dữ liệu trong subselect trở nên không theo thứ tự và do đó tôi đã gặp điều kiện "is_first_appear = 1" nhiều lần. Mã rất giống nhau, với cùng một dữ liệu, hoạt động trên Percona ok.
Radek

5

Một cách khác để gt hàng gần đây nhất cho mỗi nhóm bằng cách sử dụng truy vấn phụ, về cơ bản sẽ tính thứ hạng cho mỗi hàng cho mỗi nhóm và sau đó lọc ra các hàng gần đây nhất của bạn như với rank = 1

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

BẢN GIỚI THIỆU

Dưới đây là bản demo trực quan để xếp hạng không cho mỗi hàng để hiểu rõ hơn

Bằng cách đọc một số nhận xét về việc nếu có hai hàng có cùng giá trị trường 'home' và 'datetime' thì sao?

Truy vấn trên sẽ thất bại và sẽ trả về hơn 1 hàng cho tình huống trên. Để che đậy tình huống này, sẽ cần một tiêu chí / tham số / cột khác để quyết định hàng nào sẽ được thực hiện trong tình huống trên. Bằng cách xem tập dữ liệu mẫu, tôi giả sử có một cột khóa chính idsẽ được đặt thành tăng tự động. Vì vậy, chúng ta có thể sử dụng cột này để chọn hàng gần đây nhất bằng cách điều chỉnh cùng một truy vấn với sự trợ giúp của CASEcâu lệnh như

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

BẢN GIỚI THIỆU

Truy vấn trên sẽ chọn hàng có id cao nhất trong số các datetimegiá trị tương tự

bản demo trực quan cho thứ hạng không cho mỗi hàng


2

Tại sao không sử dụng: CHỌN nhà, MAX (datetime) NHƯ MaxDateTime, trình phát, tài nguyên TỪ topten NHÓM Ở nhà Tôi có bỏ lỡ điều gì không?


4
Điều đó sẽ chỉ hợp lệ với MySQL và chỉ các phiên bản trước 5.7 (?) Hoặc sau 5.7 bị vô hiệu hóa CHỈ_ULL_GROUP_BY, vì đó là các cột CHỌN chưa được tổng hợp / NHÓM (trình phát, tài nguyên) có nghĩa là MySQL sẽ cung cấp các giá trị được chọn ngẫu nhiên cho các giá trị đó hai trường kết quả. Sẽ không có vấn đề gì với cột người chơi vì nó tương quan với cột nhà, nhưng cột tài nguyên sẽ không tương quan với cột nhà hoặc cột thời gian và bạn không thể đảm bảo giá trị tài nguyên nào bạn nhận được.
đơn giản hóa

+1 để giải thích, NHƯNG viết câu hỏi được hỏi, truy vấn này sẽ không trả về kết expectedquả đầu ra trong phiên bản MySQL 5.6 beforevà tôi rất nghi ngờ nó sẽ hành xử khác trong phiên bản MySQL 5.7 và after.
sactiw

@simpleuser, `Sẽ không có vấn đề gì với cột người chơi vì điều đó có liên quan đến cột nhà` - bạn có thể giải thích thêm không?
Istiaque Ahmed

@IstiaqueAhmed khi tôi nhìn lại, tuyên bố đó không chính xác. Tôi đã nghĩ rằng mỗi người chơi luôn có cùng một giá trị nhà, nhưng tôi thấy bây giờ họ không có, vì vậy, vấn đề chọn ngẫu nhiên tương tự cũng sẽ xảy ra cho cột đó
đơn giản hóa

1

Thử cái này

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

Trân trọng


5
Hãy kiểm tra xem có khác biệt không, nếu hai thời gian tối đa bằng nhau ở cùng một nhà (với những người chơi khác nhau)
Maksym Gontar

bí danh cho max(datetime) datetime. Nó sẽ không làm cho bất kỳ vấn đề?
Istiaque Ahmed

Làm thế nào là datetimelựa chọn cao nhất ?
Istiaque Ahmed

1

đây là truy vấn bạn cần:

 SELECT b.id, a.home,b.[datetime],b.player,a.resource FROM
 (SELECT home,MAX(resource) AS resource FROM tbl_1 GROUP BY home) AS a

 LEFT JOIN

 (SELECT id,home,[datetime],player,resource FROM tbl_1) AS b
 ON  a.resource = b.resource WHERE a.home =b.home;

bạn có thể giải thích câu trả lời của bạn?
Istiaque Ahmed

1

@Michae Câu trả lời được chấp nhận sẽ hoạt động tốt trong hầu hết các trường hợp nhưng nó không thành công cho một câu như dưới đây.

Trong trường hợp nếu có 2 hàng có HomeID và Datetime giống nhau thì truy vấn sẽ trả về cả hai hàng, không phân biệt HomeID theo yêu cầu, cho điều đó thêm Phân biệt trong truy vấn như bên dưới.

SELECT DISTINCT tt.home  , tt.MaxDateTime
FROM topten tt
INNER JOIN
    (SELECT home, MAX(datetime) AS MaxDateTime
    FROM topten
    GROUP BY home) groupedtt 
ON tt.home = groupedtt.home 
AND tt.datetime = groupedtt.MaxDateTime

kết quả hiển thị - "# 1054 - Cột không xác định 'tt.MaxDateTime' trong 'danh sách trường'"
Istiaque Ahmed

@IstiaqueAhmed bạn có nộp MaxDatetime tức là bất kỳ tên cột nào như vậy không ..?
Manoj Kargeti

Không, bảng trong OP không có bất kỳ cột nào như vậy.
Istiaque Ahmed

xin lỗi cũng nói như vậy .. chính xác thì bạn muốn làm gì? bạn có thể gửi cấu trúc bảng và truy vấn của bạn.
Manoj Kargeti

1

Hy vọng bên dưới truy vấn sẽ cho đầu ra mong muốn:

Select id, home,datetime,player,resource, row_number() over (Partition by home ORDER by datetime desc) as rownum from tablename where rownum=1
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.