You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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则确保每个用户只返回一行结果。

原代码的错误点说明

  1. CASE语句位置错误:CASE应该作为SELECT的字段项,不能放在JOIN和WHERE之间的位置。
  2. 未处理行转列:wp_usermeta中每个用户的姓名信息是两条独立记录,直接关联会返回两行数据,必须通过聚合或多次关联将多行合并为一行,才能得到你想要的数组结构。

内容的提问来源于stack exchange,提问作者Alex Knopp

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.23 23:32:13