0

我有 2 个表 - 帖子和 postmeta。

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. 其发布状态为 Publish AND
  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。但我得到的是空的结果。我无法弄清楚它在哪里分崩离析。如何解决这个问题?

4

3 回答 3

2

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

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;
;
于 2012-06-19T16:34:00.823 回答
1

你得到一个空的结果集,因为你正在AND输入meta_value列,所以它必须同时等于两个值,这是不可能的。像这样的东西val = '1' AND val = 'both'总是会返回 false 并且没有任何行会加入。相反,您必须使用OR介于条件之间:城市 -> 1 和特色 -> h/both。

由于帖子必须同时包含 city -> 1 和 features -> h/both (不是跨列而是跨多行),因此您需要一个HAVING与 a 结合的子句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
于 2012-06-19T17:30:06.383 回答
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”子句中编写任何查询。

于 2012-06-19T16:37:33.390 回答