在 Wordpress 中使用 JOIN 进行高级 MySQL 查询

Posted

技术标签:

【中文标题】在 Wordpress 中使用 JOIN 进行高级 MySQL 查询【英文标题】:Advanced MySQL query in Wordpress with JOIN 【发布时间】:2012-01-06 23:13:07 【问题描述】:

我是 mysql 新手,我正在尝试编写一个非常高级的查询。但是,嘿!边做边学和 ***!

我可能会在不太高级的查询/查询中获取所有数据,并使用 php 对数据进行排序。但我认为它可以直接在查询中完成。

下面是我的代码。如果您不明白,请提出问题,我会尽力解释得更好。如果您发现任何错误,请帮助我更正代码。

代码将用于在我的 wordpress 页面上显示不同的字段。不同的领域将有不同的类别,例如。侧边栏博客,侧边栏页面,高亮博客,高亮页面。它几乎可以像普通帖子一样工作。

这是Wordpress的数据库结构:

http://codex.wordpress.org/images/9/9e/WP3.0-ERD.png http://codex.wordpress.org/Database_Description

问题:

我应该如何加入这些表:wp_posts、wp_term_relationships、wp_term_taxonomy、wp_terms 和 wp_postmeta?

进行高级查询是一种好习惯,还是应该使用 PHP 来处理 if/else 函数?

<?php

$id = $post->ID; // Gets the ID of current page

$query = "
SELECT wp_posts.post_content, wp_posts.ID, wp_terms.slug        # Data from two different tables

FROM wp_posts

# Cant figure out how to join the tables
INNER JOIN wp_postmeta
ON wp_posts.ID = wp_postmeta.post_id

INNER JOIN wp_term_relationships
ON wp_posts.ID = wp_term_relationships.object_id

INNER JOIN wp_term_taxonomy
ON wp_term_relationships.term_taxonomy_id = wp_term_taxonomy.term_taxonomy_id

INNER JOIN wp_terms
ON wp_term_taxonomy.term_id = wp_terms.term_id




WHERE
wp_posts.post_type = 'my-own-post-type'         # Only get specific post-type
AND
wp_posts.post_status = 'publish'                # Only get published posts


AND

# START - Only get categories specified here
(
wp_terms.slug = 'category-1'
OR
wp_terms.slug = 'category-2'
OR
wp_terms.slug = 'category-3'
OR
wp_terms.slug = 'category-4'
OR
wp_terms.slug = 'category-5'
)
# END - Only get categories specified here


AND

# I want to be able to include or exclude specific pages, even if category is the right one
# Exlude = Don't get data if current page ID is found (ID of current page will be checked in meta_value using %,$id,%)
# Include means: If include value is specifyed, then get data ONLY if ID is found (ID of current page will be checked in meta_value using %,$id,%)
# If not exclude and include are set, it should get the data

# START - Include exclude
(
# exclude is set, so check if page id match anywhere. If it IS found it it should not get the data, otherwise YES
wp_postmeta.meta_key = 'exclude' AND wp_postmeta.meta_value <> '%,$id,%'
OR
# include is set, so check if page id match anywhere. If it IS NOT found it it should not get the data, otherwise YES
wp_postmeta.meta_key = 'include' AND wp_postmeta.meta_value = '%,$id,%'
OR
# If exclude and include aren't set it should get the data
wp_postmeta.meta_key <> 'exkludera' AND wp_postmeta.meta_key <> 'include'
)
# END - Include exclude


";



$result = mysql_query($query);

while($row = mysql_fetch_array($result))


// collect all fields in category 1 (eg. sidebar)
if($row['slug'] == 'category-1')
$all_fields_from_category_1 = $all_fields_from_category_1.'
<div id="field-sidebar">
'.$row['post_content'].'
</div>
';

// collect all fields in category 1 (eg. highlight)
if($row['slug'] == 'category-2')
$all_fields_from_category_2 = $all_fields_from_category_2.'
<div id="field-highlight">
'.$row['post_content'].'
</div>
';



 // end while



// sidebar
echo '<div id="container-sidebar">'.
$all_fields_from_category_1.
'</div>';


// highlight
echo '<div id="container-highlight">'.
$all_fields_from_category_1.
'</div>';

?>

新版本,新问题:

SELECT DISTINCT wp_posts.post_content, wp_posts.ID, wp_terms.slug
FROM wp_posts
JOIN wp_postmeta ON wp_posts.ID = wp_postmeta.post_id
JOIN wp_term_relationships ON wp_posts.ID = wp_term_relationships.object_id
JOIN wp_term_taxonomy ON wp_term_relationships.term_taxonomy_id = wp_term_taxonomy.term_taxonomy_id
JOIN wp_terms ON wp_term_taxonomy.term_id = wp_terms.term_id
WHERE wp_posts.post_type = 'my-own-fields'

AND wp_posts.post_status = 'publish'
AND wp_terms.slug IN
('field1', 'field2', 'field3', 'field4', 'field5', 'field6')
AND
(
wp_postmeta.meta_key = 'exlude' AND wp_postmeta.meta_value <> '$id'
OR wp_postmeta.meta_key = 'include' AND wp_postmeta.meta_value = '$id'
OR wp_postmeta.meta_key <> 'exlude' AND wp_postmeta.meta_value <> 'include' #LAST ROW
)

即使设置了排除或包含,“#LAST ROW”也会返回数据。那是因为它匹配表 wp_postmeta 中的另外两行。

wp_postmeta 表示例:

meta_id     post_id     meta_key    meta_value
1           30          include     18
2           30          _edit_lock  1322225789:1
3           30          _edit_last  1

如果找不到 post_id 的 meta_key inklude 或 exclude 我想返回数据...

我想返回数据时的示例场景:

meta_id     post_id     meta_key    meta_value
2           30          _edit_lock  1322225789:1
3           30          _edit_last  1

知道如何解决这个问题吗? 一条语句说:如果没有为当前 ID 找到具有排除或包含的行。返回数据。

更多示例:

post_id 是 30。

如果情景是:

meta_id     post_id     meta_key    meta_value
1           30          include     18
2           30          _edit_lock  1322225789:1
3           30          _edit_last  1

然后我想找回 wp_posts.post_content、wp_posts.ID 和 wp_terms.slug 只要 $id 为 18。

如果情景是:

meta_id     post_id     meta_key    meta_value
1           30          exclude     18
2           30          _edit_lock  1322225789:1
3           30          _edit_last  1

然后我想取回 wp_posts.post_content、wp_posts.ID 和 wp_terms.slug,只要 $id 不是 18。

如果情景是:

meta_id     post_id     meta_key    meta_value
2           30          _edit_lock  1322225789:1
3           30          _edit_last  1

那我想取回wp_posts.post_content、wp_posts.ID和wp_terms.slug。

【问题讨论】:

您能否提供一个带有排除项的 Post_id 示例以及您希望返回的内容 亚当,你明白我想要达到的目的吗? 我相信我会。当您Exclude: 18 时,您不希望post_id 的任何记录id=18,对吗?它比简单地格式化原始查询更复杂。我会再考虑一下。 并非如此。如果我删除“#LAST ROW”,则排除和包含功能 allredy 完美。问题是何时设置了包含或排除。然后我没有取回数据(我想要的)。 Se 表 wp_postmeta 的最后三个 senarios... 在加入 wp_posts 表之前,我能否以某种方式在表 wp_postmeta 上使用“GROUP BY wp_postmeta.post_id”? 【参考方案1】:

您的连接已正确完成。删除 cmets 和多余的行时,您会发现查询并没有那么复杂。我所做的唯一真正的改变是将 wp_terms.slug 的 OR 列表更改为 IN 语句。这样做只是为了减少代码重复,清理外观,而不是更改功能。

SELECT p.post_content, p.ID, t.slug
FROM wp_posts AS p
INNER JOIN wp_postmeta AS pm ON p.ID = pm.post_id
INNER JOIN wp_term_relationships AS tr ON p.ID = tr.object_id
INNER JOIN wp_term_taxonomy AS tt ON tr.term_taxonomy_id = tt.term_taxonomy_id
INNER JOIN wp_terms AS t ON tt.term_id = t.term_id
WHERE p.post_type = 'my-own-post-type'
   AND p.post_status = 'publish'
   AND t.slug IN
      ('category-1', 'category-2', 'category-3', 'category-4', 'category-5')
   AND
   (
      ( pm.meta_key = 'exclude' AND pm.meta_value <> '$id' )
         OR ( pm.meta_key = 'include' AND pm.meta_value = '$id' )
         OR ( pm.meta_key <> 'exclude' AND pm.meta_value <> 'include' )
   )

【讨论】:

你是对的!加入有效!艰难我对最后一个有问题:### OR pm.meta_key 'exclude' AND pm.meta_key 'include' ### 问题是帖子上设置了另外两个 meta_key(另外两行): _edit_last 和 _edit_lock。如果未设置 meta_key 排除或包含,我想获取一次数据。即使设置了包含或排除,上面的代码也会给我返回数据。关于如何解决这个问题的任何想法?例如。 "如果找不到meta_key包含或排除,则获取一次数据" @Hakan 我很难理解你的意思。您能否更新您的问题并解释您要查找的内容? @Hakan 我添加了一个 OR 语句,可以解决您的问题。我将等待您的回复/阅读您更新的问题以确保。

以上是关于在 Wordpress 中使用 JOIN 进行高级 MySQL 查询的主要内容,如果未能解决你的问题,请参考以下文章

wordpress 高级自定义字段 google map api key

MySQL 高级 (二) ---join关联查询

高级T-SQL进阶系列 下篇:使用 CROSS JOIN 介绍高级T-SQL

在 Wordpress 中使用 ACF(高级自定义字段)显示自定义帖子标题的下拉菜单

如何检查 Wordpress 高级自定义字段插件中的字段组?

在 WordPress 中查看高级自定义字段所需的能力