mySQL - JOINS和ORDER BY一个/零/ null值

时间:2012-03-22 08:58:35

标签: mysql sql-order-by

我很难接受那个问题。

SELECT SQL_CALC_FOUND_ROWS wp_posts.* 
FROM wp_posts 
    LEFT JOIN wp_postmeta p1 ON ( wp_posts.ID = p1.post_id AND p1.meta_key = '_vip_post' ) 
    LEFT JOIN wp_postmeta p2 ON ( wp_posts.ID = p2.post_id AND p2.meta_key = '_thumbnail_id' ) 
WHERE 1=1 
    AND wp_posts.post_type = 'housing' 
    AND (wp_posts.post_status = 'publish') 
GROUP BY wp_posts.ID 
ORDER BY
    COALESCE( p1.meta_key, 0 )+0 DESC,
    p1.meta_key DESC,
    if( p2.meta_key = '' or p2.meta_key is null, 1, 0) ASC, 
    wp_posts.post_date DESC LIMIT 0, 20

是的,这是WordPress的帖子表。我要两次加入postmeta表。 p1.meta_key 01null存储在longtext字段类型中。我需要将p1.meta_key = 1排在最前面的行。相反,它会将p1.meta_key不是null的行放在最前面,并按最后两个ORDER BY指令对它们进行排序。

更新

看起来我需要在此查询中确定我的优先级。如果我从查询结尾删除wp_posts.post_date DESC,或者只删除ORDER BY:

p1.meta_key+0 = 1 DESC,
IF ( p2.meta_key = '' or p2.meta_key is null, 2, 1 )

行按照我想要的方式返回,但不是按时间顺序返回。

这就是我得到的

+-----------------------+   +-------------+   +-----------------+
|       post_date       | + |  _vip_post  | + |  _thumbnail_id  |
+-----------------------+   +-------------+   +-----------------+
|  2012-03-18 21:47:33  |   |      0      |   |       533       |
|  2012-03-18 21:36:49  |   |      0      |   |       230       |
|  2012-03-18 20:19:50  |   |      0      |   |       170       |
|  2012-03-18 17:19:52  |   |      1      |   |        56       |
|  2012-03-20 10:42:00  |   |     null    |   |      null       |
|  2012-03-19 18:56:10  |   |     null    |   |      null       |
|  2012-03-16 03:12:32  |   |     null    |   |        ''       |
|  2012-03-15 16:40:22  |   |     null    |   |        ''       |
+-----------------------+   +-------------+   +-----------------+

这就是我需要的方式

+-----------------------+   +-------------+   +-----------------+
|       post_date       | + |  _vip_post  | + |  _thumbnail_id  |
+-----------------------+   +-------------+   +-----------------+
|  2012-03-18 17:19:52  |   |      1      |   |        56       |
|  2012-03-18 21:47:33  |   |      0      |   |       533       |
|  2012-03-18 21:36:49  |   |      0      |   |       230       |
|  2012-03-18 20:19:50  |   |      0      |   |       170       |
|  2012-03-20 10:42:00  |   |     null    |   |      null       |
|  2012-03-19 18:56:10  |   |     null    |   |      null       |
|  2012-03-16 03:12:32  |   |     null    |   |        ''       |
|  2012-03-15 16:40:22  |   |     null    |   |        ''       |
+-----------------------+   +-------------+   +-----------------+

1 个答案:

答案 0 :(得分:1)

尝试...

order by
   case when p1.meta_key is null then 3
        when p1.meta_key = 1 then 1
        when p1.meta_key is 0 then 2 end,
   case p2.meta_key is null then 2
        else 1 end,
   wp_posts.post_date DESC

此处的订单首先检查p1.meta_key。首先检查NULL并设置为3.如果不是,如果为1,则使用1作为其第一级排序顺序。如果= 0,那么2作为其排序顺序。

现在,在上面的排序中,您希望日期按降序排序,但是将任何NULL日期放在列表的END处,因此我们需要限定是否存在空值...所以第二种情况有效类似于第一个。如果日期为空,则将其设为SECOND,如果它有日期,则为第一个。

最后,实际日期级别。按照每个p1.meta_key分组的最新日期(所有实际日期将出现在任何空值之前)的发布日期降序排序。