我有2张桌子 - 帖子和帖子。
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
我正在尝试运行一个查询,它会给我一个包含以下条件的帖子列表:
我正在尝试的查询是
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 :(得分: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;
;
答案 1 :(得分:1)
您获得一个空结果集,因为您AND
meta_value
列val = '1' AND val = 'both'
,因此它必须同时等于两个值,这是不可能的。像OR
这样的东西总是返回false,没有任何行会加入。相反,您必须在条件之间使用HAVING
:city - > 1和特色 - > H /两。
由于帖子必须包含两个城市 - > 1和特色 - > h / both(不是跨列而是跨多行),你需要一个GROUP BY
子句和LIKE
一起来确保每个帖子连接两行,满足两个条件......不是一个或另一个。
此外,检查1
的存在是否有很多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
。您可以改为使用FIND_IN_SET:
{{1}}
答案 2 :(得分: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'子句中编写任何查询。