使用元表中的多个条目Compex MySQL Left Join

时间:2010-09-17 12:10:00

标签: mysql wordpress metadata left-join

我正在尝试创建单个查询以从主表(WordPress用户表)和用户元表中获取信息。

如果您不熟悉WP DB架构:wp_users保存基本用户信息及其ID,wp_usermeta包含ID,meta_key和meta_value。

假设我想让所有拥有某些meta_keys和meta_values的用户。这是我目前的查询(基于可用的meta_keys通过PHP生成):

SELECT ID, 
user_email, 
user_login, 
first_name.meta_value as first_name,
last_name.meta_value as last_name,
phone_number.meta_value as phone_number,
wp_capabilities.meta_value as wp_capabilities 
FROM wp_users, 
(select * from wp_usermeta where meta_key = 'first_name') as first_name,
(select * from wp_usermeta where meta_key = 'last_name') as last_name,
(select * from wp_usermeta where meta_key = 'phone_number') as phone_number,
(select * from wp_usermeta where meta_key = 'wp_capabilities') as wp_capabilities 
WHERE  
ID = first_name.user_id AND 
ID = last_name.user_id AND 
ID = phone_number.user_id AND 
ID = wp_capabilities.user_id  AND 
wp_wpi_capabilities.meta_value LIKE '%administrator%'   
ORDER BY first_name

这样做很好,但是如果某个用户缺少meta_key,例如'last_name',则根本不会返回该用户行。所以我真正需要的是一种为缺少元键返回Null值的方法。

现在我有一个非常hackish的函数,它为所有没有给定meta_key的用户创建空白的meta_keys和meta_values,这样就可以返回它们。这是一种可怕的方式,但是当你拥有超过一千个用户时,你需要添加一种新类型的meta_key。

如果有人这样做,或者我需要更好地解释,请告诉我。

谢谢。

1 个答案:

答案 0 :(得分:14)

将usermeta加入条件放在连接中,而不是苦苦于子查询:

SELECT
    ID, user_email, user_login, 
    first_name.meta_value as first_name,
    last_name.meta_value as last_name,
    phone_number.meta_value as phone_number,
    wp_capabilities.meta_value as wp_capabilities 
FROM wp_users
    JOIN wp_usermeta AS wp_capabilities ON wp_capabilities.user_id=ID
        AND wp_capabilities.meta_key='wp_capabilities'
    LEFT JOIN wp_usermeta AS first_name ON first_name.user_id=ID
        AND first_name.meta_key='first_name'
    LEFT JOIN wp_usermeta AS last_name ON last_name.user_id=ID
        AND last_name.meta_key='last_name'
    LEFT JOIN wp_usermeta AS phone_number ON phone_number.user_id=ID
        AND phone_number.meta_key='phone_number'
WHERE
    wp_capabilities.meta_value LIKE '%administrator%'
ORDER BY
    first_name