在MySQL中获取每个组的最新行

时间:2019-06-07 13:16:38

标签: mysql sql group-by max greatest-n-per-group

我正在尝试获取每个Paper.material的所有最新Book.isbn。我正在使用left来获取每个Book.isbn的基础,因为它们可以有一个表示修订的后缀,例如:'X1726748384Z1'或'X1837943875Z2'等。我尝试了{{1}但是它没有用,因为MySQL 5.7不支持此功能。我该如何工作?

目标

对于每个over partition byBook.isbn

X

查询

select left(Book.isbn, 11) BaseISBN, Paper.material, Book.date
from Book
  join Page on Book.id = Page.book_id
  join Paper on Page.id = Paper.page_id
where Book.name = 'world'
  and left(Book.isbn, 11) = X  <--
  and Page.name = 'test'
order by Book.date desc
limit 1

退货

select left(Book.isbn, 11) BaseISBN, Paper.material, max(Book.date)
from Book
  join Page on Book.id = Page.book_id
  join Paper on Page.id = Paper.page_id
where Book.name = 'world'
  and left(Book.isbn, 11) in('X1726748384', 'X1837943875')
  and Page.name = 'test'
group by left(Book.isbn, 11);

应退还

| Book.isbn   | Paper.material | max(Book.date)       |
|-------------|----------------|----------------------|
| X1726748384 | 10134248300B   | 2018-01-01T00:00:00Z |
| X1837943875 | 10985782343F   | 2021-01-01T00:00:00Z |
etc...

SQL FIDDLE

和相同的DDL:

CREATE TABLE `Book` (
    `id` INT NOT NULL AUTO_INCREMENT,
    `isbn` varchar(255),
    `name` varchar(255),
    `date` DATETIME,
    PRIMARY KEY (`id`)
);

CREATE TABLE `Page` (
    `id` INT NOT NULL AUTO_INCREMENT,
    `name` varchar(255),
    `book_id` INT NOT NULL,
    PRIMARY KEY (`id`)
);

CREATE TABLE `Paper` (
    `id` INT NOT NULL AUTO_INCREMENT,
    `material` varchar(255),
    `page_id` INT NOT NULL,
    PRIMARY KEY (`id`)
);

ALTER TABLE `Page` ADD CONSTRAINT `Page_fk0` FOREIGN KEY (`book_id`) REFERENCES `Book`(`id`);
ALTER TABLE `Paper` ADD CONSTRAINT `Paper_fk0` FOREIGN KEY (`page_id`) REFERENCES `Page`(`id`);

INSERT INTO `Book` (`isbn`, `name`, `date`) VALUES 
('X1234234403', 'hello', '2016-01-01'),
('X1726748384', 'world', '2017-01-01'),
('X1726748384Z1', 'world', '2018-01-01'),
('X1837943875', 'world', '2019-01-01'),
('X1837943875Z1', 'world', '2020-01-01'),
('X1837943875Z2', 'world', '2021-01-01');

INSERT INTO `Page` (`name`, `book_id`) VALUES 
('bla', 1),
('test', 2),
('test', 3),
('test', 4),
('test', 5),
('test', 6);

INSERT INTO `Paper` (`material`, `page_id`) VALUES 
('10134248300A', 1),
('10134248300B', 2), 
('10134248300C', 2), 
('10985782343D', 3), 
('10985782343E', 3), 
('10985782343F', 4), 
('10985782343G', 5), 
('10985782343H', 6);

1 个答案:

答案 0 :(得分:1)

“等等”。试图了解结果中应该包含和不应包含的内容时,它不是很有用。

尽管如此,也许您正在追求这样的东西...

SELECT b.*
     , z.material
  FROM book b
  JOIN
     ( SELECT LEFT(isbn,11) isbn11
            , MAX(date) date 
         FROM book 
        WHERE 
            ( isbn LIKE 'X1726748384%' 
           OR isbn LIKE 'X1837943875%' 
            ) 
          AND name = 'world'
        GROUP 
           BY isbn11
     ) x
    ON x.isbn11 = LEFT(b.isbn,11)
   AND x.date = b.date
  JOIN page y
    ON y.book_id = b.id
  JOIN paper z
    ON z.page_id = y.id
 WHERE y.name = 'test';

+----+---------------+-------+---------------------+--------------+
| id | isbn          | name  | date                | material     |
+----+---------------+-------+---------------------+--------------+
|  3 | X1726748384Z1 | world | 2018-01-01 00:00:00 | 10985782343D |
|  3 | X1726748384Z1 | world | 2018-01-01 00:00:00 | 10985782343E |
|  6 | X1837943875Z2 | world | 2021-01-01 00:00:00 | 10985782343H |
+----+---------------+-------+---------------------+--------------+
3 rows in set (0.00 sec)