这两天研究了查询和解析键值对形式的数据库数据操作.
先来看一个用到子查询的SQL语句:
$sql = "
SELECT `user_id`,`meta_key`,`meta_value`
FROM `wp_usermeta`
WHERE user_id
IN
(SELECT author FROM wp_flag_gallery )
AND
(meta_key = 'nickname' OR meta_key = 'description')
ORDER BY user_id, meta_key";
这是一个WordPress插件: flash-album-gallery 的表.这个插件我会专门撰文介绍,作为Flex相册的后台极为有用.
通过将相册中的用户信息作为WHERE的目标,查询出了几个键值对形式的数组.
这里我还不知道如何直接在SQL中将拥有同一个id的几个行合并为一个,所以只好在PHP端进行这个工作.
看看PHP端的解析方法:
/**
* 查询WordPress中相册作者的相关信息
*
* @return array 每个子项为一个user的信息.<br />
*
*/
function getGalleryAuthorsInfo ()
{
if (count($this->users_array) > 0)
{
$this->users_array = array(0);
}
$sql = "
SELECT `user_id`,`meta_key`,`meta_value`
FROM `wp_usermeta`
WHERE user_id
IN
(SELECT author FROM wp_flag_gallery )
AND
(meta_key = 'nickname' OR meta_key = 'description')
ORDER BY user_id, meta_key";
$result = $this->query($sql);
//清空可能存在的用户信息
if (count($this->users_array) > 0)
{
$this->users_array = array();
}
//合并用户信息
if ($result && is_array($result))
{
//对返回的数组排序,根据'user_id'列,把同样'user_id'的项目集中在一起
asort($result);
$isNewUser = TRUE;
$curUser = array();
for ($i = 0; $i < count($result); $i ++)
{
$info = $result[$i];
if ($isNewUser)
{
$isNewUser = FALSE;
$curUser['user_id'] = $info['user_id'];
}
//新的信息
switch ($info['meta_key'])
{
case 'description':
$curUser['description'] = $info['meta_value'];
break;
case 'nickname':
$curUser['nickname'] = $info['meta_value'];
break;
}
if (!$isNewUser && $curUser['description'] != NULL && $curUser['nickname'] != NULL)
{
array_push($this->users_array, $curUser);
$isNewUser = TRUE;
$curUser = array();
}
} //end for
} //end if
else
{
return 0;
} //end else
return $this->users_array;
} //end function
整理结果:
//获取WordPress的用户信息: getGalleryAuthorsInfo()
Array (
[0] => Array (
[user_id] => 3
[description] => 您的个性独一无二,让我们为您展示最独特的个性风采吧!
[nickname] => 个性写真 )
[1] => Array (
[user_id] => 4
[description] => 幸福情侣的图片作品
[nickname] => 幸福情侣 )
)
output: 2
这个日志的关键在于:
1,学习了使用IN关键字的子查询,这里有一点要注意,在WHERE 中如果同时使用AND和OR关键字,要注意AND的优先级比OR高,所以如果不加()的话可能会造成OR的条件被忽略.
比如:
...
AND (meta_key = 'nickname' OR meta_key = 'description')
...
如果不加上括号,meta_key = ''这个条件就不会被考虑.
另外,如果使用ORDER BY子句,应保证它是SELECT查询最后一个子句,否则会报错.
2,在整理这种情况的返回数据时,最好别忘了先给$result数组排序,用asort()函数可以做到保持键值对关系的排序.虽然在数据库查询的时候已经做了ORDER BY的排序,但是在PHP端再次排序能保证PHP端方法的强壮性.