WordPress用户和用户元数据 - 将一个表中的多行连接成另一个表中的一行

20

我想创建一个视图,从wp_users和wp_usermeta表中获取数据,以便我可以从外部应用程序查询视图的行。基本身份验证详细信息存储在wp_users中(例如用户名、密码、电子邮件、id),其他字段以键/值对的形式存储在wp_usermeta表中。

wp_users表的结构如下:

id | login | password | email
-----------------------------
1  | bsmith| abc123   | b@foo.com
2  | jjones| def456   | k@bah.com

wp_usermeta表的结构如下:

id | user_id | meta_key | meta_value
------------------------------------
1  | 1       | firstname| bob
2  | 1       | lastname | smith
3  | 1       | country  | denmark
4  | 2       | firstname| jan
5  | 2       | lastname | jones
6  | 2       | country  | germany

我想要得到这样的MYSQL视图数据:

id | login | password | email    | firstname | lastname | country
-----------------------------------------------------------------
1  | bsmith| abc123   | b@foo.com| bob       | smith    | denmark
2  | jjones| def456   | k@bah.com| jan       | jones    | germany

我知道我至少需要在wp_users和wp_usermeta之间执行一个内联接,但是我还需要在wp_usermeta内执行子查询来将这些行连接起来。

当然,获取用户行的查询非常简单:

select u1.id, u1.login, u1.password, u1.email from wp_users u1

我用以下查询语句获取meta行:

select m1.user_id, m1.meta_value as firstname, m2.meta_value as lastname, m3.meta_value as country
from wp_usermeta m1
join wp_usermeta m2 on (m1.user_id = m2.user_id and m2.meta_key = 'last_name')
join wp_usermeta m3 on (m2.user_id = m3.user_id and m3.meta_key = 'country')
where m1.meta_key = 'first_name'

那么我该如何将这两个查询连接在一起 - u1的数据和u1.id = m1.userid的行?


你是否计划根据某些meta_value属性搜索用户?如果没有,你可以将属性存储在单个序列化的meta_value字段中(json编码或php序列化)。 - Ben
@Ben:不,一个外部应用程序将连接并交互式地查询数据。 - frumbert
3个回答

38
据我所知,你正在正确地进行操作,只需要把它们放在一起即可:
SELECT
    u1.id,
    u1.login,
    u1.password,
    u1.email,
    m1.meta_value AS firstname,
    m2.meta_value AS lastname,
    m3.meta_value AS country
FROM wp_users u1
JOIN wp_usermeta m1 ON (m1.user_id = u1.id AND m1.meta_key = 'first_name')
JOIN wp_usermeta m2 ON (m2.user_id = u1.id AND m2.meta_key = 'last_name')
JOIN wp_usermeta m3 ON (m3.user_id = u1.id AND m3.meta_key = 'country')
WHERE
    -- CONDITIONS ON the user you want to select based any field

Gar,你是对的,我当然看到了复杂的解决方案!谢谢。 - frumbert
2
这非常有帮助。对于其他用户,如果您正在WordPress中进行操作(我认为OP不是),则需要将wp_usermeta和wp_users替换为$wpdb->usermeta和$wpdb->users。仅供后人参考。非常有用的答案。 - Jake
这真的为我节省了大量时间! - Scorpius
1
抱歉,Toote,stackoverflow 不允许我为您的答案投超过一票。虽然这是旧查询,但它非常有效。谢谢。 - Vinith
1
谢谢,它对我有用。在使用之前,我的查询需要大约65秒才能执行,现在只需要3秒就能执行了。 - MANJEET

19

我发现Toote的解决方案可行,但在MySQL数据库中表现很差,在执行“select * from users_with_meta_view”时需要约17秒。

我通过使用以下结构的视图将其降至0.0054秒:

CREATE OR REPLACE VIEW users_with_meta_view AS
SELECT
    u.id,
    u.user_login AS login,
    u.user_pass AS password,
    u.user_email AS email,
    (select meta_value from wp_usermeta where user_id = u.id and meta_key = 'first_name' limit 1) as first_name,
    (select meta_value from wp_usermeta where user_id = u.id and meta_key = 'last_name' limit 1) as last_name,
    (select meta_value from wp_usermeta where user_id = u.id and meta_key = 'country' limit 1) as country
FROM wp_users u

1
$sql= "SELECT
       u1.parent_id,
       m1.meta_value AS headline,
       m2.meta_value AS profilephoto
       FROM wp_vandor u1
       JOIN wp_usermeta m1 ON (m1.user_id = u1.child_id AND m1.meta_key = 'headline')
       JOIN wp_usermeta m2 ON (m2.user_id = u1.child_id AND m2.meta_key = 'profilephoto')
       WHERE m1.user_id != $currentuser_id";

$classifieds = $wpdb->get_results($sql);

foreach ($classifieds as $classified) { ?>
     <p><?php echo $classified->profilephoto; ?></p>
     <h3><?php echo $classified->headline; ?></h3>
<?php } ?>

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接