我有一个日期列,其中包含日期值或null。我用它来保存产品的到期日期。我想编写一个查询来按以下顺序获取它们:尚未过期,没有过期(null)和过期。
例如,假设今天是5月15日:
prd_id prd_name Expiry Date
-----------------
1 name1 May 16
2 name2 May 17
3 name3 May 18
4 name4 May 21
5 namex null
6 namex null
7 namex null
8 namex May 14
9 namex May 12
(空值表示没有过期)
我该怎么做?
答案 0 :(得分:1)
您可以尝试以下语法: -
SELECT *
FROM YOUR_TABLE
ORDER BY CASE WHEN expire_date > CURDATE() THEN 1 END,
WHEN expire_date IS NULL THEN 2 Desc END,
WHEN expire_date < CURDATE() THEN 3 Desc END;
答案 1 :(得分:1)
基本上,您将一起加入三个不同的查询:
SELECT * FROM (SELECT * FROM `product_entries` WHERE expires_on IS NOT NULL AND expires_on > CURDATE()
ORDER BY expires_on ASC) a
UNION ALL
SELECT * FROM (SELECT * FROM `product_entries` WHERE expires_on IS NULL) b
UNION ALL
SELECT * FROM (SELECT * FROM `product_entries` WHERE expires_on IS NOT NULL AND expires_on <= CURDATE()
ORDER BY expires_on DESC) c
第一个返回那些没有过期的,第二个返回没有过期的,第三个返回过期的条目。
请注意,您希望将expires_on
列编入索引。另外,正如您在第三个查询中所看到的,我将当前日期计为过期。如果您希望当天计算为未过期,请在第三个查询中将<=
更改为<
,并在第一个查询中将>
更改为>=
。< / p>
另一种选择是使用CASE条款(如果您不关心每个条目的顺序,只要未过期的是在顶部,永久产品在中间,并且过期的条目位于底部)
mysql> SELECT * FROM product_entries ORDER BY CASE
-> WHEN expires_on >= CURDATE() THEN 3
-> WHEN expires_on IS NULL THEN 2
-> WHEN expires_on < CURDATE() THEN 1
-> END DESC;
+----+-------------+
| id | expire_date |
+----+-------------+
| 9 | 2015-05-11 |
| 8 | 2015-05-06 |
| 7 | 2015-05-01 |
| 10 | NULL |
| 6 | 2015-04-26 |
| 5 | 2015-04-21 |
| 4 | 2015-04-16 |
| 3 | 2015-04-11 |
| 2 | 2015-04-06 |
| 1 | 2015-04-01 |
+----+-------------+