mysql 来自同一列的多个连接具有不同的键

Posted

技术标签:

【中文标题】mysql 来自同一列的多个连接具有不同的键【英文标题】:mysql muliple joins from same colums with different keys 【发布时间】:2017-06-12 23:29:20 【问题描述】:

在使用下表进行第二次联接时,我需要一些帮助。我之前从这里得到了一些帮助,有人建议我需要添加第二个 JOIN,但是,这是我遇到困难并需要一些帮助的地方。

wp-posts

  -----------------
  id | Post_Title | 
  -----------------
  01 | Event 1    | 
  -----------------
  02 | Event 2    | 
  -----------------

wp-postmeta

-------------------------------------------------------
  meta_id  | post_id | meta_key          | meta_value |
  -----------------------------------------------------
  456      | 01      | _EventStartDate   | 01/01/2017 |
  -------------------------------------------------- ---
  789      | 01      | _EventEndDate     | 05/02/2017 |
  -----------------------------------------------------

我追求的最终结果是这样的;

标题 - 开始于 <_eventstartdate> 并结束于 <_eventenddate>

我使用以下方法获取数据:

    $result = $wpdb->get_results ( "
SELECT $wpdb->posts.ID, $wpdb->posts.post_content, $wpdb->postmeta.meta_id, 

$wpdb->postmeta.post_id, $wpdb->postmeta.meta_key, $wpdb->postmeta.meta_value, $wpdb->posts.post_title 


FROM $wpdb->posts INNER JOIN $wpdb->postmeta ON $wpdb->posts.ID = $wpdb->postmeta.post_id 

WHERE $wpdb->postmeta.meta_key = '_EventStartDate' 

ORDER BY $wpdb->postmeta.meta_value " );

现在我被告知 WHERE 只会返回一行,并且我需要使用 $wpdb-&gt;postmeta.meta_key = '_EventStartDate' 进行第二次 JOIN,但经过数小时的尝试实现这一点后,我根本无法获取和返回数据.

如果有人可以帮助解决这个问题,那将非常有帮助,因为我还有一些问题想写,而且我猜我也需要对他们使用相同的主体。

感谢阅读!!

【问题讨论】:

【参考方案1】:

您可以像这样使用group by 在一行中获取 start_date 和 end_date:

select
    t1.*,
    max(case when meta_key = '_EventStartDate' then meta_value end) start_date,
    max(case when meta_key = '_EventEndDate' then meta_value end) end_date
from wp_posts t1
inner join wp_postmeta t2
on t1.id = t2.post_id
group by t1.post_id;

如果启用ONLY_FULL_GROUP_BY,则将group by子句更改为:

group by t1.post_id, t1.Post_title;

【讨论】:

^1 鼓舞人心的好答案【参考方案2】:

假设 wp-postmeta 中的每个帖子只有一个 _EventStartDate 和一个 _EventEndDate,一个简化的查询将是:

SELECT p.post_title, pm1.meta_value AS start_date, pm2.meta_value AS end_date 
FROM wp-posts p 
     INNER JOIN wp-postmeta pm1
             ON  p.post_id     = pm1.post_id
            AND  pm1.meta_ekey = '_EventStartDate'  
     INNER JOIN wp-postmeta pm2
             ON  p.post_id     = pm2.post_id
            AND  pm2.meta_ekey = '_EventEndDate'

【讨论】:

【参考方案3】:

您可以使用单个内部连接来完成,按帖子 ID 分组,然后拆分开始日期和结束日期:

select 
wpposts.post_content,
substring_index(GROUP_CONCAT(meta_value order by str_to_date(meta_value,'%d/%m/%Y')), ',', 1) as start_date ,
substring_index(GROUP_CONCAT(meta_value order by str_to_date(meta_value,'%d/%m/%Y')), ',', -1) as end_date
from wpposts inner join wppostmeta
on wpposts.id = wppostmeta.post_id
where wppostmeta.meta_key='_EventStartDate' or wppostmeta.meta_key='_EventEndDate'
group by wppostmeta.post_id

【讨论】:

这工作做得很好,谢谢。如果可能的话,第 3 行和第 4 行实际上是做什么的?我假设 group by wppostmeta.post_id 按帖子 ID 对查询中的所有内容进行分组? 不,分组是按最后一行进行的;因为您有两个 meta_value 值(对于具有相同 post_id 的每组记录),第 3-4 行需要连接它们(group_concat 默认使用“,”连接)以使它们可用于选择部分,然后使用 substring_index 拆分它们,取第 3 行 (start_date) 中 "," 之前的所有内容和第 4 行 (end_date) 中 "," 之后的所有内容。

以上是关于mysql 来自同一列的多个连接具有不同的键的主要内容,如果未能解决你的问题,请参考以下文章

SQL 显示来自同一列的多个值

从单个表中检索具有不同值的同一列的多个输出时的性能问题

MySQL:创建具有自动增量的表并将生成的值与同一表的不同列的值连接起来

ValueError:列的长度必须与具有多个输出的键的长度相同

MYSQL加入来自同一个表的多个列[关闭]

如何使用 Nhibernate 从连接两个具有所有 id 的表中选择只有一个不同列的多个列是 UNIQUEIDENTIFIER