WP环境下SQL SELECT语句CASE用法问题求助
解决WordPress多表查询中获取用户姓名的问题
你的问题核心在于CASE语句的用法错误,以及没考虑wp_usermeta表的键值对存储特性。wp_usermeta中每个用户的first_name、last_name是单独的行,直接按你原来的写法会返回多行数据,且CASE的语法位置也不对。
下面提供两种可行的解决方案:
方法1:多次关联wp_usermeta表
通过两次INNER JOIN分别匹配first_name和last_name的记录,直接获取对应字段,逻辑直观:
$query = $wpdb->prepare( "SELECT s.user_id, u.user_email, m_first.meta_value AS first_name, m_last.meta_value AS last_name FROM wp_user_stages s INNER JOIN wp_users u ON s.user_id = u.ID INNER JOIN wp_usermeta m_first ON s.user_id = m_first.user_id AND m_first.meta_key = 'first_name' INNER JOIN wp_usermeta m_last ON s.user_id = m_last.user_id AND m_last.meta_key = 'last_name' WHERE s.quest_comp = 0 AND s.registered = %s ", '2024-05-11' ); $users = $wpdb->get_results($query, ARRAY_A);
方法2:使用条件聚合(CASE+MAX)
通过聚合函数将同一用户的多行meta数据合并为一行,适合需要获取多个meta字段的场景:
$query = $wpdb->prepare( "SELECT s.user_id, u.user_email, MAX(CASE WHEN m.meta_key = 'first_name' THEN m.meta_value END) AS first_name, MAX(CASE WHEN m.meta_key = 'last_name' THEN m.meta_value END) AS last_name FROM wp_user_stages s INNER JOIN wp_users u ON s.user_id = u.ID INNER JOIN wp_usermeta m ON s.user_id = m.user_id WHERE s.quest_comp = 0 AND s.registered = %s AND m.meta_key IN ('first_name', 'last_name') -- 过滤冗余meta,提升查询效率 GROUP BY s.user_id, u.user_email ", '2024-05-11' ); $users = $wpdb->get_results($query, ARRAY_A);
这里用MAX()是因为同一用户的同一个meta_key只会有一行数据,MAX()会直接取出对应值,GROUP BY则确保每个用户只返回一行结果。
原代码的错误点说明
- CASE语句位置错误:CASE应该作为SELECT的字段项,不能放在JOIN和WHERE之间的位置。
- 未处理行转列:wp_usermeta中每个用户的姓名信息是两条独立记录,直接关联会返回两行数据,必须通过聚合或多次关联将多行合并为一行,才能得到你想要的数组结构。
内容的提问来源于stack exchange,提问作者Alex Knopp
相关产品推荐
相关产品推荐

