我希望使用一个查询来实现下面所述的目标,而不是像我目前必须使用的多个查询。
我遇到的问题是来自wp_usermeta
表的数据在2x列中存储为meta_key
/ meta_value
,而不是每种类型的数据都包含在{2}列中。自己的专栏。虽然这样做的理由是有道理的,但这确实意味着我在这一点上难以接受。
有问题的数据库适用于WordPerss网站,任何人都希望复制此内容。
对于每个至少有一个图像/视频帖子的用户,我需要抓住以下详细信息 -
+-----------------------+---------------+------------------------------------------------+
| Description | Table | Column |
+-----------------------+---------------+------------------------------------------------+
| User ID | `wp_users` | `ID` |
| Display Name | `wp_users` | `display_name` |
| First Name | `wp_usermeta` | `meta_value` (WHERE `meta_key` = 'first_name' |
| Description | `wp_usermeta` | `meta_value` (WHERE `meta_key` = 'description' |
| Facebook profile link | `wp_usermeta` | `meta_value` (WHERE `meta_key` = 'facebook' |
| Google+ profile link | `wp_usermeta` | `meta_value` (WHERE `meta_key` = 'google_plus' |
| Twitter profile link | `wp_usermeta` | `meta_value` (WHERE `meta_key` = 'twitter' |
+-----------------------+---------------+------------------------------------------------+
首先,我选择至少有1张图片/视频帖子的所有用户的ID和显示名称(这是一个查询) -
SELECT DISTINCT `wp_users`.`ID`, `wp_users`.`display_name`
FROM `wp_posts`
INNER JOIN `wp_users`
WHERE `wp_posts`.`post_type` = "attachment"
AND `wp_posts`.`post_status` = "inherit"
AND `wp_posts`.`post_author` = `wp_users`.`ID`
AND (
`wp_posts`.`post_mime_type` LIKE "image%"
OR `wp_posts`.`post_mime_type` LIKE "video%"
)
接下来,我必须遍历第一个查询的每个结果,并为每个结果选择第一个名称,描述和社交媒体链接(这是user_id = 2
的一个示例) -
SELECT `wp_usermeta`.`meta_key`, `wp_usermeta`.`meta_value`
FROM `wp_usermeta`
WHERE `wp_usermeta`.`user_id` = 2
AND (
`wp_usermeta`.`meta_key` = 'first_name'
OR `wp_usermeta`.`meta_key` = 'description'
OR `wp_usermeta`.`meta_key` = 'facebook'
OR `wp_usermeta`.`meta_key` = 'google_plus'
OR `wp_usermeta`.`meta_key` = 'twitter'
);
作为运行第二个查询的循环的一部分,我还必须将这些结果插入到第一个查询的结果中。所有这些不仅意味着额外的代码,而且会导致更长的执行时间。
我的完整代码可在此处找到 - http://pastebin.com/P2jv3WTt
这个目标是否可以通过MySQL实现,或者它根本不是它能够做到的事情?感谢。
我尝试按如下方式加入wp_usermeta
表,将结果输出为命名列,但是存在一个问题 - 唯一的结果是针对每个{{1}的条目的用户在meta_key
表中,但有些人没有(例如,没有Twitter个人资料链接)。
wp_usermeta
答案 0 :(得分:1)
最直接的解决方案就是这样。只需为您需要的每个元值进行连接。
使用LEFT OUTER JOIN
代替INNER JOIN
加入元数据,您仍然可以保留其中某些元数据不存在的用户。
SELECT DISTINCT u.ID, u.DisplayName,
fn.meta_value AS firstname, fb.meta_value AS facebook, (etc.)
FROM wp_Users u
INNER JOIN wp_posts p ON p.post_author = u.ID
LEFT OUTER JOIN wp_usermeta fn ON fn.UserId = u.ID AND fn.meta_key = 'first_name'
LEFT OUTER JOIN wp_usermeta fb ON fb.UserId = u.ID AND fb.meta_key = 'facebook'
--- (etc. for each meta column you need to join)
WHERE p.post_type = 'attachment'
AND p.post_status = 'inherit'
AND (p.post_mime_type LIKE 'image%'
OR p.post_mime_type LIKE 'video%')
答案 1 :(得分:1)
我会选择这样的东西:
SELECT DISTINCT
`wp_users`.`ID`,
`wp_users`.`display_name`,
`wp_usermeta`.`meta_key`,
`wp_usermeta`.`meta_value`
FROM
`wp_posts`
INNER JOIN
`wp_users` ON (`wp_posts`.`post_author` = `wp_users`.`ID`)
LEFT JOIN
`wp_usermeta` ON (`wp_usermeta`.`user_id` = `wp_users`.`ID`)
WHERE
`wp_posts`.`post_type` = 'attachment'
AND `wp_posts`.`post_status` = 'inherit'
AND (`wp_posts`.`post_mime_type` LIKE 'image%'
OR `wp_posts`.`post_mime_type` LIKE 'video%')
AND `wp_usermeta`.`meta_key`
IN ('first_name', 'description', 'facebook', 'google_plus', 'twitter');
即使没有与用户关联的元数据,LEFT JOIN也必须返回帖子和用户。
答案 2 :(得分:0)
SELECT meta.user_id, meta.meta_key, meta.meta_value
FROM wp_usermeta meta JOIN wp_posts posts
ON posts.post_author = meta.user_id
WHERE posts.post_type = "attachment"
AND posts.post_status = "inherit"
AND posts.post_mime_type RLIKE "^(image|video)"
AND meta_key IN ('first_name', 'description','facebook','google_plus','twitter');
请记住,wp_posts.post_author和wp_usermeta.user_id应该是索引,否则此查询将会很慢。
如果你在wp_usermeta上有一个联合索引,那就更好了:user_key (user_id, meta_key)
。您可以使用以下命令添加它:
ALTER TABLE wp_usermeta ADD KEY user_key(user_id, meta_key);
PS如果你还需要来自wp_users表的display_name,那么你也必须加入它:
SELECT meta.user_id, users.display_name, meta.meta_key, meta.meta_value
FROM wp_usermeta meta JOIN wp_posts posts
ON posts.post_author = meta.user_id
JOIN wp_users users
ON users.id = meta.user_id
WHERE posts.post_type = "attachment"
AND posts.post_status = "inherit"
AND posts.post_mime_type RLIKE "^(image|video)"
AND meta_key IN ('first_name', 'description','facebook','google_plus','twitter');