2012-06-19 166 views
0

我有2个表 - posts和postmeta。MySQL查询返回空

posts 
ID title category post_status post_type  

1 ABC  cat-1 Publish  Store 
2 DEF  cat-2 Publish  Store 
3 GHI  cat-3 Publish  Store 
4 JKL  cat-2 Publish  Store 
5 XYZ  cat-5 Draft  Store 
6 MNO  cat-9 Publish  Article 

postmeta 
meta_id post_id meta_key meta_value 

109  1  city   1 
110  1  featured  h 
111  2  city   1,2 
112  2  featured  both 
113  3  city   2,3 
114  3  featured  both 
115  4  city   1 
116  4  featured  n 
117  5  city   1,4 
118  5  featured  h 
119  6  city   1 
120  6  featured  h 

我想运行一个查询,会给我的帖子的列表,它具有以下条件:

  1. 谁对城市价值有1 AND
  2. 其特征值为h或两者均为AND
  3. 其发布状态为发布AN d
  4. 后,其类型为商店
  5. 责令其按标题

我想查询是

SELECT DISTINCT posts.ID , posts.*, postmeta.* 
      FROM posts, postmeta 
      WHERE posts.ID = postmeta.post_id 
      AND (postmeta.meta_value = 'h' OR postmeta.meta_value = 'both') 

AND (postmeta.meta_key = 'post_city_id' AND (postmeta.meta_value LIKE '%,1,%' OR postmeta.meta_value LIKE '%1,%' OR postmeta.meta_value LIKE '%,1%' OR postmeta.meta_value LIKE '%1%')) 

      AND posts.post_status = 'Publish' 
      AND posts.post_type = 'Store' 

      ORDER BY (SELECT postmeta.meta_value from postmeta where (posts.ID = postmeta.post_id) and postmeta.meta_key LIKE '%home_featured_type%') asc, posts.post_title LIMIT 0,6 

正确的回报将是ID为1和2,即ABC和DEF。但是我得到空的结果。我无法弄清楚它在哪里分崩离析。这怎么解决?

+0

为了通过posts.title我在这里有误提到posts.post_title查询...这将是posts.title – Ranadeep

回答

2

这里是一个固定的查询,但我仍然不明白神秘的ORDER BY (SELECT) thingie。

http://sqlfiddle.com/#!2/5ce5a/19

SELECT DISTINCT posts.ID , posts.*, postmeta_city.*, postmeta_featured.* 

FROM  posts 

INNER JOIN postmeta AS postmeta_city 
    ON  postmeta_city.post_id = posts.ID 
    AND  postmeta_city.meta_key = 'city' 
    AND ( postmeta_city.meta_value LIKE '%,1,%' 
     OR postmeta_city.meta_value LIKE '%1,%' 
     OR postmeta_city.meta_value LIKE '%,1%' 
     OR postmeta_city.meta_value LIKE '%1%' 
     ) 
INNER JOIN postmeta AS postmeta_featured 
    ON  postmeta_featured.post_id = posts.ID 
    AND  postmeta_featured.meta_key = 'featured' 
    AND ( postmeta_featured.meta_value = 'h' 
     OR postmeta_featured.meta_value = 'both' 
     ) 

WHERE posts.post_status = 'Publish' 
    AND posts.post_type = 'Store' 

ORDER BY (
    SELECT postmeta.meta_value 
    FROM postmeta 
    WHERE (posts.ID = postmeta.post_id) 
     AND postmeta.meta_key LIKE '%home_featured_type%' 
) asc, 
    posts.title 

LIMIT 0,6; 
; 

与其他人的想法更新,请给予好评他们:

http://sqlfiddle.com/#!2/5ce5a/33

SELECT DISTINCT posts.ID , posts.*, postmeta_city.*, postmeta_featured.* 

FROM  posts 

INNER JOIN postmeta AS postmeta_city 
    ON postmeta_city.post_id = posts.ID 
    AND postmeta_city.meta_key = 'city' 
    AND FIND_IN_SET('1', postmeta_city.meta_value) 

INNER JOIN postmeta AS postmeta_featured 
    ON postmeta_featured.post_id = posts.ID 
    AND postmeta_featured.meta_key = 'featured' 
    AND postmeta_featured.meta_value IN ('h','both') 

WHERE posts.post_status = 'Publish' 
    AND posts.post_type = 'Store' 

ORDER BY (
    SELECT postmeta.meta_value 
    FROM postmeta 
    WHERE (posts.ID = postmeta.post_id) 
     AND postmeta.meta_key LIKE '%home_featured_type%' 
) asc, 
    posts.title 

LIMIT 0,6; 
; 
+0

精彩。我正在使用更新的解决方案。完美的作品。万分感谢。 – Ranadeep

0

试试这个:

SELECT DISTINCT posts.ID , posts.*, postmeta.* 
      FROM posts AS p INNER JOIN postmeta AS pm 
      WHERE p.ID = pm.post_id 
      AND (pm.meta_value in ('h','both') 

AND (pm.meta_key = 'city' AND 
(pm.meta_value LIKE '%,1,%' OR pm.meta_value LIKE '%1,%' OR pm.meta_value LIKE '%,1%' OR pm.meta_value LIKE '%1%')) 

      AND posts.post_status = 'Publish' 
      AND posts.post_type = 'Store' 

      ORDER BY p.title LIMIT 0,6 

由于您只希望按标题排序,因此不需要在'order by'子句中编写任何查询。

1

您会得到一个空的结果集,因为您的AND列为meta_value列,所以它必须同时等于两个值,这是不可能的。类似于val = '1' AND val = 'both'将始终返回false,并且没有行会加入。相反,您必须在以下条件之间使用OR:city - > 1和featured - > h/both。由于帖子必须同时包含city - > 1和featured - > h/both(它们不跨列,但跨多行),所以您需要HAVING子句与GROUP BY一起确保每个帖子都会加入有两排,满足两个条件......不是一个或另一个。

此外,这是一个可怕的很多LIKE的检查是否存在1。您可以使用FIND_IN_SET代替:

SELECT 
    * 
FROM 
    posts a 
INNER JOIN 
    postmeta b ON a.ID = b.post_id 
    AND 
    (
     (b.meta_key = 'city' AND FIND_IN_SET('1', b.meta_value) > 0) 
     OR 
     (b.meta_key = 'featured' AND b.meta_value IN ('h', 'both')) 
    ) 
WHERE 
    a.post_status = 'Publish' 
    AND a.post_type = 'Store' 
GROUP BY 
    a.ID 
HAVING 
    COUNT(*) = 2 
ORDER BY 
    a.title 
+0

http://sqlfiddle.com/#!2/5ce5a/34 – biziclop

+0

虽然我已经接受biziclop的更新解决方案,但我感谢您的解释。我将为未来记住这一点。万分感谢。 – Ranadeep