Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/61.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
MySQL:如何使用3个键查找最新的行不像听起来那么简单_Mysql - Fatal编程技术网

MySQL:如何使用3个键查找最新的行不像听起来那么简单

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

我有一个包含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_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 dateb.minor\u version,但a.release\u date