我有这个表:table1和四个可变$START_MONTH
$START_YEAR
$END_MONTH
$END_YEAR
返回:月:1,年:2014 和 3,2015
+----+-----+-------+------+-------------+
| ID | DAY | MONTH | YEAR | DESCRIPTION |
+----+-----+-------+------+-------------+
| 1 | 1 | 1 | 2014 | Product 1 |
| 2 | 1 | 2 | 2015 | Product 2 |
| 3 | 2 | 3 | 2014 | Product 1 |
| 4 | 10 | 1 | 2015 | Product 3 |
| 5 | 9 | 5 | 2015 | Product 3 |
+----+-----+-------+------+-------------+
SELECT
DATE_FORMAT (CONCAT (DAY,' ', MONTH,' ',YAR), GET_FORMAT(DATE,'EUR')) AS NEW_DATA,
DESCRIPTION
FROM table1
WHERE
NEW_DATA BETWEEN $START_MONTH . $START_YEAR AND $END_MONTH . $END_YEAR
我需要返回以下各行: 1.2014 和 3.2015 。谢谢!
答案 0 :(得分:2)
在MySQL中,您可以按组合列进行过滤:
SELECT *
FROM table1
WHERE (`YEAR`, `MONTH`) >= (2014,1)
AND (`YEAR`, `MONTH`) <= (2015,3)
http://sqlfiddle.com/#!9/87000/2
更新:正如Strawberry所说,MySQL不会为这种情况使用索引。但这不是不可能的 - MySQL只是缺少这种优化。据我所知,PostgreSQL适用于这种索引范围检查。所以我们希望MySQL / MariaDB将来能够支持它。
但是,如果遇到性能问题,可以为年份范围添加冗余条件:
WHERE (`YEAR`, `MONTH`) >= (2014,1)
AND (`YEAR`, `MONTH`) <= (2015,3)
AND `YEAR` >= 2014
AND `YEAR` <= 2015
这样,MySQL将首先使用YEAR
或YEAR, MONTH
(或任何以YEAR, MONTH, DAY
开头的索引)等索引按YEAR
过滤行。
我知道的所有替代方案都不是非常易读,也没有人可以使用索引:
WHERE DATE(CONCAT_WS('-', `YEAR`, `MONTH`, 1)) >= '2014-01-01'
AND DATE(CONCAT_WS('-', `YEAR`, `MONTH`, 1)) <= '2015-03-01'
或者
WHERE (`YEAR` = 2014 AND `MONTH` >= 1)
OR (`YEAR` = 2015 AND `MONTH` >= 3)
OR (`YEAR` > 2014 AND `YEAR` < 2015)
如果你每隔几毫秒都在战斗,你也可以创建一个indexed generated (virtual) column (MySQL 5.7):
`DATE` AS STR_TO_DATE(CONCAT_WS('-', `YEAR`, `MONTH`, `DAY`),'%Y-%m-%d') VIRTUAL KEY
并查询如下:
WHERE `DATE` >= '2014-01-01'
AND `DATE` < '2015-04-01'
答案 1 :(得分:0)
SELECT
DATE_FORMAT (CONCAT (DAY,' ', MONTH,' ',YEAR), GET_FORMAT(DATE,'EUR')) AS NEW_DATA,
DESCRIPTION
FROM table1
WHERE
(YEAR BETWEEN $START_YEAR AND $END_YEAR)
AND (MONTH BETWEEN $START_MONTH AND $END_MONTH)