MySQL之间喜欢约会

时间:2015-12-09 20:04:52

标签: mysql sql

以下作品:

SELECT * FROM myTable WHERE date_created BETWEEN '2014-10-05' AND '2015-12-31';

但是我尝试了以下内容:

SELECT * FROM myTable WHERE date_created BETWEEN '2014-10%' AND '2015-12%';

这项工作是否有办法选择带有通配符的两个日期?

SELECT * FROM myTable WHERE year(date_created) BETWEEN 2014 AND 2015 AND month(date_created) BETWEEN 10 AND 12

我也尝试过如上所述,也没有选择范围,它只选择20142015的所有内容以及只有10个月的内容和12

有没有办法让我做以下工作?

SELECT * FROM myTable WHERE date_created BETWEEN '2014-10%' AND '2015-12%';

4 个答案:

答案 0 :(得分:1)

您可以将DATE_FORMAT用于此

SELECT * FROM myTable WHERE DATE_FORMAT(date_created,"%Y-%m") BETWEEN 
DATE_FORMAT('2014-10-05',"%Y-%m") AND DATE_FORMAT('2015-12-31',"%Y-%m") ;

答案 1 :(得分:1)

使用LAST_DAY功能获取当月的最后一天。

WHERE date_created BETWEEN DATE_FORMAT('2014-10-05', '%Y-%m-01') AND LAST_DAY('2015-12-02')

这比在DATE_FORMAT列上使用date_created的解决方案更好,因为它可以使用该列上的索引。

答案 2 :(得分:0)

虽然@GoudaElalfy解决方案完成了这项工作,但该查询可能存在性能问题。它不会在列date_created上使用简单的索引。

请参阅您的评论,其中说明您实际需要的是构建涵盖整个月份的查询的方法:

  

我希望我能在SQL中获得一系列的月份,所以我没有必要在java中找到这个月的最后一天。因为这样做:BETWEEN' 2014-10-01' AND' 2015-12-31'我需要知道上个月的nr。

您可以计算这些值并将该列保留在WHERE子句中,以便它可以从中获得简单的索引。

  1. 您知道每个月都有第一天,这将是您扫描索引/表格的起点。
  2. 您需要计算一个月的最后一天,因为它不是静态的,这将是您在表/索引扫描过程中的终点。
  3. 执行此操作的一种方法是使用LAST_DAY()函数

    SELECT * 
    FROM myTable 
    WHERE date_created BETWEEN DATE_FORMAT('2014-10-05', '%Y-%m-01') AND LAST_DAY('2015-12-31');
    

    第二种方式是使用一些简单的计算

    SELECT * 
    FROM myTable 
    WHERE date_created BETWEEN DATE_FORMAT('2014-10-05', '%Y-%m-01') AND DATE_FORMAT('2015-12-31' + INTERVAL 1 MONTH, '%Y-%m-01') - INTERVAL 1 DAY;
    

答案 3 :(得分:0)

抱歉,在WHERE子句“DATE_FORMAT(date_created,”%Y-%m“)”中使用函数和表中的字段不是一个好主意。所以数据库必须在表中的每一行上执行该功能。这将是一个完整的表扫描。

我创建了一个包含3000行的测试表。以下是此查询的执行计划,您可以看到它们读取所有(3000)行。

MariaDB > EXPLAIN
    -> SELECT * FROM myTable WHERE date_created BETWEEN
    -> DATE_FORMAT('2015-01-05',"%Y-%m") AND DATE_FORMAT('2015-01-31',"%Y-%m") ;
+------+-------------+---------+-------+---------------+--------------+---------+------+------+--------------------------+
| id   | select_type | table   | type  | possible_keys | key          | key_len | ref  | rows | Extra                    |
+------+-------------+---------+-------+---------------+--------------+---------+------+------+--------------------------+
|    1 | SIMPLE      | myTable | index | date_created  | date_created | 4       | NULL | 3000 | Using where; Using index |
+------+-------------+---------+-------+---------------+--------------+---------+------+------+--------------------------+

最好将开始和结束条件构建为常量,如此

创建开始日期:

SELECT DATE_FORMAT('2015-01-05','%Y-%m-01');

创建结束日期:

添加一个月,在月初设置,低于1秒

SELECT DATE_FORMAT(DATE_FORMAT('2015-02-07' + INTERVAL 1 MONTH,'%Y-%m-01') -INTERVAL 1 SECOND,'%y-%m-%d');

完整查询是这样的:

SELECT * FROM myTable WHERE date_created
  BETWEEN
    DATE_FORMAT('2015-01-05','%Y-%m-01')
  AND
    DATE_FORMAT(DATE_FORMAT('2015-02-07' + INTERVAL 1 MONTH,'%Y-%m-01')
    -INTERVAL 1 SECOND,'%y-%m-%d');

在执行计划中,您可以看到他们使用索引并且只选择177行

+------+-------------+---------+-------+---------------+--------------+---------+------+------+--------------------------+
| id   | select_type | table   | type  | possible_keys | key          | key_len | ref  | rows | Extra                    |
+------+-------------+---------+-------+---------------+--------------+---------+------+------+--------------------------+
|    1 | SIMPLE      | myTable | range | date_created  | date_created | 4       | NULL |  177 | Using where; Using index |
+------+-------------+---------+-------+---------------+--------------+---------+------+------+--------------------------+