我仍然通过编写简单的程序来学习PHP和MySql。在我的最新项目中,我遇到了一个问题,你可能会发现这个问题非常简单,但是我被卡住了。
我有一张这样的表:
id | text | create_date | active | featured | featured_end
---+-------------+----------------------+--------+----------+--------------------
1 |Some text 1 | 2016-02-10 17:32:51 | 1 | 0 | 0000-00-00 00:00:00
2 |Some text 2 | 2016-02-09 17:32:51 | 1 | 1 | 2016-03-05 17:32:51
3 |Some text 3 | 2016-02-08 17:32:51 | 1 | 1 | 2016-03-05 17:32:51
4 |Some text 4 | 2016-02-07 17:32:51 | 0 | 0 | 0000-00-00 00:00:00
5 |Some text 5 | 2016-02-06 17:32:51 | 1 | 0 | 0000-00-00 00:00:00
6 |Some text 6 | 2016-02-05 17:32:51 | 1 | 0 | 0000-00-00 00:00:00
7 |Some text 7 | 2016-02-04 17:32:51 | 1 | 1 | 2016-03-05 17:32:51
8 |Some text 8 | 2016-02-03 17:32:51 | 1 | 0 | 0000-00-00 00:00:00
9 |Some text 9 | 2016-02-02 17:32:51 | 0 | 0 | 0000-00-00 00:00:00
10 |Some text 10 | 2016-02-01 17:32:51 | 1 | 1 | 2016-03-05 17:32:51
我需要使用一些过滤器从此表中获取所有结果:
1)结果必须仅包括active = 1
2)featured = 1必须位于结果集的开头
3)如果feature = 1,那么featured_end必须大于now()
我试过这个(没有用):
SELECT * FROM `table` WHERE `active` = 1
UNION SELECT * FROM `table` WHERE `featured` = 1
HAVING `featured_end` > now()
ORDER BY `featured`
DESC, `create_date` DESC
这个也不起作用:
SELECT * FROM (
(SELECT * FROM `table` WHERE `active` = 1)
UNION
(SELECT * FROM `table` WHERE `featured` = 1 AND `featured_end` > NOW())
) table
ORDER BY `featured` DESC
显然,我错过了一些东西,或者我完全走错了路。你能指引我走正确的道路吗?
答案 0 :(得分:1)
我没有对此进行测试,但它应该可以胜任。
SELECT *
FROM `table`
WHERE `active` = 1
AND (
(`featured` = 1 AND `featured_end` > now())
OR `featured` = 0
)
ORDER BY `featured` DESC
答案 1 :(得分:0)
您似乎希望根据您发布的最后一个查询使用子查询。您的查询非常接近(对于该解决方案),但它需要一些小的更改。
由于每一行都有唯一的id
,因此您可以轻松使用选择ID的子查询添加到结果中。
SELECT *
FROM `table`
WHERE `active` = 1 OR
`id` IN (
SELECT `id`
FROM `table`
WHERE `featured` = 1 AND
`featured_end` > NOW()
)
ORDER BY `featured` DESC
如您所见,您可以在子查询中选择id
字段。然后使用带有id IN(...)
子句的WHERE
在主查询中包含所选行。由于性能原因,您只选择子查询中的id
字段,其他字段将被省略,并且主要SELECT
查询将包含这些字段,这一点非常重要。
但是看起来也可以使用此策略(在单个查询中定义整个WHERE
子句):
SELECT *
FROM `table`
WHERE `active` = 1 AND ((
`featured` = 1 AND
`featured_end` > now()
) OR `featured` = 0
)
ORDER BY
`featured` DESC
答案 2 :(得分:0)
SELECT *
FROM table
WHERE active = 1 AND ((CASE WHEN featured = 1 THEN featured_end ELSE NOW()) >= NOW())
ORDER BY featured DESC
答案 3 :(得分:0)
您可以使用单个查询或一对联合查询来执行此操作。单个查询看起来更简单,但在WHERe中需要OR来限制索引的使用。
SELECT *
FROM `table`
WHERE `active` = 1
UNION
SELECT * FROM `table`
WHERE `featured` = 1
AND `featured_end` > now()
ORDER BY `featured` DESC,
`create_date` DESC