单个mysql表中的多个选择查询

时间:2016-03-01 13:57:28

标签: mysql

我仍然通过编写简单的程序来学习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 

显然,我错过了一些东西,或者我完全走错了路。你能指引我走正确的道路吗?

4 个答案:

答案 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