MySQL:如何使用3个键查找最新的行不像听起来那么简单
我有一个包含3列的产品表,可用于确定产品版本:主要版本、次要版本和发布日期 我需要一个查询,以尽可能快的速度返回包含最新产品版本的行 在我看来,最新版本可以这样确定: a) 新的主要版本:MySQL:如何使用3个键查找最新的行不像听起来那么简单,mysql,Mysql,我有一个包含3列的产品表,可用于确定产品版本:主要版本、次要版本和发布日期 我需要一个查询,以尽可能快的速度返回包含最新产品版本的行 在我看来,最新版本可以这样确定: a) 新的主要版本: a.major_version = MAX(major_version) AND a.major_version > any other major_version a.major_version = MAX(major_version) AND a.major_version = b.major_v
a.major_version = MAX(major_version) AND
a.major_version > any other major_version
a.major_version = MAX(major_version) AND
a.major_version = b.major_version AND
a.minor_version > b.minor_version AND
a.release_date >= b.release_date
b) 新的次要版本:
a.major_version = MAX(major_version) AND
a.major_version > any other major_version
a.major_version = MAX(major_version) AND
a.major_version = b.major_version AND
a.minor_version > b.minor_version AND
a.release_date >= b.release_date
c) 现有版本的“静默更新”:
a.major_version = MAX(major_version) AND
a.major_version = b.major_version AND
a.minor_version = b.minor_version AND
a.release_date > b.release_date
示例数据:
CREATE TABLE mytest
(
id int(10) NOT NULL,
major_version int(10) NOT NULL,
minor_version int(10) NOT NULL,
release_date datetime NOT NULL,
PRIMARY KEY(id)
);
truncate table mytest;
insert into mytest values(1,1,1,'2012-02-26');
insert into mytest values(2,1,2,'2012-02-26');
insert into mytest values(3,1,3,'2012-02-26');
insert into mytest values(4,2,1,'2012-02-26');
insert into mytest values(5,2,2,'2012-02-26');
insert into mytest values(6,2,2,'2012-02-27');
我的脑子僵住了。。一个查询就可以做到这一点吗?如果您愿意通过添加额外的列来更改表,我有一个简单的解决方案 设置以下内容
- 添加一个名为major\u minor的列,该列包含值major\u version*100+minor\u version
- 添加一个关于主要内容和发布日期的索引
- 现在只需在索引后面获取最大值
use test
DROP TABLE IF EXISTS mytest;
CREATE TABLE mytest
(
id int(10) NOT NULL,
major_version int(10) NOT NULL,
minor_version int(10) NOT NULL,
major_minor int(10) DEFAULT 0,
release_date datetime NOT NULL,
PRIMARY KEY(id),
KEY release_order_ndx (major_minor,release_date)
);
insert into mytest (id,major_version,minor_version,release_date) values
(1,1,1,'2012-02-26'),(2,1,2,'2012-02-26'),(3,1,3,'2012-02-26'),
(4,2,1,'2012-02-26'),(5,2,2,'2012-02-26'),(6,2,2,'2012-02-27');
UPDATE mytest SET major_minor = major_version * 100 + minor_version;
这是装的
mysql> use test
Database changed
mysql> DROP TABLE IF EXISTS mytest;
Query OK, 0 rows affected (0.03 sec)
mysql> CREATE TABLE mytest
-> (
-> id int(10) NOT NULL,
-> major_version int(10) NOT NULL,
-> minor_version int(10) NOT NULL,
-> major_minor int(10) DEFAULT 0,
-> release_date datetime NOT NULL,
-> PRIMARY KEY(id),
-> KEY release_order_ndx (major_minor,release_date)
-> );
Query OK, 0 rows affected (0.07 sec)
mysql> insert into mytest (id,major_version,minor_version,release_date) values
-> (1,1,1,'2012-02-26'),(2,1,2,'2012-02-26'),(3,1,3,'2012-02-26'),
-> (4,2,1,'2012-02-26'),(5,2,2,'2012-02-26'),(6,2,2,'2012-02-27');
Query OK, 6 rows affected (0.06 sec)
Records: 6 Duplicates: 0 Warnings: 0
mysql> UPDATE mytest SET major_minor = major_version * 100 + minor_version;
Query OK, 6 rows affected (0.07 sec)
Rows matched: 6 Changed: 6 Warnings: 0
mysql>
现在,只需按主描述、发布日期描述查询表和订单
mysql> select * from mytest order by major_minor desc, release_date desc;
+----+---------------+---------------+-------------+---------------------+
| id | major_version | minor_version | major_minor | release_date |
+----+---------------+---------------+-------------+---------------------+
| 6 | 2 | 2 | 202 | 2012-02-27 00:00:00 |
| 5 | 2 | 2 | 202 | 2012-02-26 00:00:00 |
| 4 | 2 | 1 | 201 | 2012-02-26 00:00:00 |
| 3 | 1 | 3 | 103 | 2012-02-26 00:00:00 |
| 2 | 1 | 2 | 102 | 2012-02-26 00:00:00 |
| 1 | 1 | 1 | 101 | 2012-02-26 00:00:00 |
+----+---------------+---------------+-------------+---------------------+
6 rows in set (0.02 sec)
最后,只需按MAJUR\U minor desc、release\U date desc limit 1查询表和订单
mysql> select * from mytest order by major_minor desc, release_date desc limit 1;
+----+---------------+---------------+-------------+---------------------+
| id | major_version | minor_version | major_minor | release_date |
+----+---------------+---------------+-------------+---------------------+
| 6 | 2 | 2 | 202 | 2012-02-27 00:00:00 |
+----+---------------+---------------+-------------+---------------------+
1 row in set (0.00 sec)
mysql>
mysql> select * from mytest order by major_version desc,minor_version desc, release_date desc limit 1;
+----+---------------+---------------+---------------------+
| id | major_version | minor_version | release_date |
+----+---------------+---------------+---------------------+
| 6 | 2 | 2 | 2012-02-27 00:00:00 |
+----+---------------+---------------+---------------------+
1 row in set (0.00 sec)
mysql>
试试看
如果您不想添加major_minor,那么让我们使用原始表
您需要在这三列上添加索引
mysql> use test
Database changed
mysql> DROP TABLE IF EXISTS mytest;
Query OK, 0 rows affected (0.03 sec)
mysql> CREATE TABLE mytest
-> (
-> id int(10) NOT NULL,
-> major_version int(10) NOT NULL,
-> minor_version int(10) NOT NULL,
-> release_date datetime NOT NULL,
-> PRIMARY KEY(id),
-> KEY release_order_ndx (major_version,minor_version,release_date)
-> );
Query OK, 0 rows affected (0.13 sec)
mysql> insert into mytest (id,major_version,minor_version,release_date) values
-> (1,1,1,'2012-02-26'),(2,1,2,'2012-02-26'),(3,1,3,'2012-02-26'),
-> (4,2,1,'2012-02-26'),(5,2,2,'2012-02-26'),(6,2,2,'2012-02-27');
Query OK, 6 rows affected (0.10 sec)
Records: 6 Duplicates: 0 Warnings: 0
只需按主要版本描述、次要版本描述、发布日期描述限制1查询表和订单
mysql> select * from mytest order by major_minor desc, release_date desc limit 1;
+----+---------------+---------------+-------------+---------------------+
| id | major_version | minor_version | major_minor | release_date |
+----+---------------+---------------+-------------+---------------------+
| 6 | 2 | 2 | 202 | 2012-02-27 00:00:00 |
+----+---------------+---------------+-------------+---------------------+
1 row in set (0.00 sec)
mysql>
mysql> select * from mytest order by major_version desc,minor_version desc, release_date desc limit 1;
+----+---------------+---------------+---------------------+
| id | major_version | minor_version | release_date |
+----+---------------+---------------+---------------------+
| 6 | 2 | 2 | 2012-02-27 00:00:00 |
+----+---------------+---------------+---------------------+
1 row in set (0.00 sec)
mysql>
如果您愿意通过添加一列来更改表,我有一个简单的解决方案 设置以下内容
- 添加一个名为major\u minor的列,该列包含值major\u version*100+minor\u version
- 添加一个关于主要内容和发布日期的索引
- 现在只需在索引后面获取最大值
use test
DROP TABLE IF EXISTS mytest;
CREATE TABLE mytest
(
id int(10) NOT NULL,
major_version int(10) NOT NULL,
minor_version int(10) NOT NULL,
major_minor int(10) DEFAULT 0,
release_date datetime NOT NULL,
PRIMARY KEY(id),
KEY release_order_ndx (major_minor,release_date)
);
insert into mytest (id,major_version,minor_version,release_date) values
(1,1,1,'2012-02-26'),(2,1,2,'2012-02-26'),(3,1,3,'2012-02-26'),
(4,2,1,'2012-02-26'),(5,2,2,'2012-02-26'),(6,2,2,'2012-02-27');
UPDATE mytest SET major_minor = major_version * 100 + minor_version;
这是装的
mysql> use test
Database changed
mysql> DROP TABLE IF EXISTS mytest;
Query OK, 0 rows affected (0.03 sec)
mysql> CREATE TABLE mytest
-> (
-> id int(10) NOT NULL,
-> major_version int(10) NOT NULL,
-> minor_version int(10) NOT NULL,
-> major_minor int(10) DEFAULT 0,
-> release_date datetime NOT NULL,
-> PRIMARY KEY(id),
-> KEY release_order_ndx (major_minor,release_date)
-> );
Query OK, 0 rows affected (0.07 sec)
mysql> insert into mytest (id,major_version,minor_version,release_date) values
-> (1,1,1,'2012-02-26'),(2,1,2,'2012-02-26'),(3,1,3,'2012-02-26'),
-> (4,2,1,'2012-02-26'),(5,2,2,'2012-02-26'),(6,2,2,'2012-02-27');
Query OK, 6 rows affected (0.06 sec)
Records: 6 Duplicates: 0 Warnings: 0
mysql> UPDATE mytest SET major_minor = major_version * 100 + minor_version;
Query OK, 6 rows affected (0.07 sec)
Rows matched: 6 Changed: 6 Warnings: 0
mysql>
现在,只需按主描述、发布日期描述查询表和订单
mysql> select * from mytest order by major_minor desc, release_date desc;
+----+---------------+---------------+-------------+---------------------+
| id | major_version | minor_version | major_minor | release_date |
+----+---------------+---------------+-------------+---------------------+
| 6 | 2 | 2 | 202 | 2012-02-27 00:00:00 |
| 5 | 2 | 2 | 202 | 2012-02-26 00:00:00 |
| 4 | 2 | 1 | 201 | 2012-02-26 00:00:00 |
| 3 | 1 | 3 | 103 | 2012-02-26 00:00:00 |
| 2 | 1 | 2 | 102 | 2012-02-26 00:00:00 |
| 1 | 1 | 1 | 101 | 2012-02-26 00:00:00 |
+----+---------------+---------------+-------------+---------------------+
6 rows in set (0.02 sec)
最后,只需按MAJUR\U minor desc、release\U date desc limit 1查询表和订单
mysql> select * from mytest order by major_minor desc, release_date desc limit 1;
+----+---------------+---------------+-------------+---------------------+
| id | major_version | minor_version | major_minor | release_date |
+----+---------------+---------------+-------------+---------------------+
| 6 | 2 | 2 | 202 | 2012-02-27 00:00:00 |
+----+---------------+---------------+-------------+---------------------+
1 row in set (0.00 sec)
mysql>
mysql> select * from mytest order by major_version desc,minor_version desc, release_date desc limit 1;
+----+---------------+---------------+---------------------+
| id | major_version | minor_version | release_date |
+----+---------------+---------------+---------------------+
| 6 | 2 | 2 | 2012-02-27 00:00:00 |
+----+---------------+---------------+---------------------+
1 row in set (0.00 sec)
mysql>
试试看
如果您不想添加major_minor,那么让我们使用原始表
您需要在这三列上添加索引
mysql> use test
Database changed
mysql> DROP TABLE IF EXISTS mytest;
Query OK, 0 rows affected (0.03 sec)
mysql> CREATE TABLE mytest
-> (
-> id int(10) NOT NULL,
-> major_version int(10) NOT NULL,
-> minor_version int(10) NOT NULL,
-> release_date datetime NOT NULL,
-> PRIMARY KEY(id),
-> KEY release_order_ndx (major_version,minor_version,release_date)
-> );
Query OK, 0 rows affected (0.13 sec)
mysql> insert into mytest (id,major_version,minor_version,release_date) values
-> (1,1,1,'2012-02-26'),(2,1,2,'2012-02-26'),(3,1,3,'2012-02-26'),
-> (4,2,1,'2012-02-26'),(5,2,2,'2012-02-26'),(6,2,2,'2012-02-27');
Query OK, 6 rows affected (0.10 sec)
Records: 6 Duplicates: 0 Warnings: 0
只需按主要版本描述、次要版本描述、发布日期描述限制1查询表和订单
mysql> select * from mytest order by major_minor desc, release_date desc limit 1;
+----+---------------+---------------+-------------+---------------------+
| id | major_version | minor_version | major_minor | release_date |
+----+---------------+---------------+-------------+---------------------+
| 6 | 2 | 2 | 202 | 2012-02-27 00:00:00 |
+----+---------------+---------------+-------------+---------------------+
1 row in set (0.00 sec)
mysql>
mysql> select * from mytest order by major_version desc,minor_version desc, release_date desc limit 1;
+----+---------------+---------------+---------------------+
| id | major_version | minor_version | release_date |
+----+---------------+---------------+---------------------+
| 6 | 2 | 2 | 2012-02-27 00:00:00 |
+----+---------------+---------------+---------------------+
1 row in set (0.00 sec)
mysql>
能否将日期列指定为毫秒?如果是这样的话,就很容易只根据最新版本的发布日期来确定它。你有没有理由不想按主要版本描述、次要版本描述、发布日期描述限制1进行订购?你的订单没有明确规定——如果a.major\u version=b.major version,a.minor\u version>b.minor\u version,但a.release\u date