微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

MySQL中的层次结构数据到PHP多维数组

只是为了学习sql,我想用一个简单的父子建立一个层次结构.就像堆栈溢出徽章一样(父:问题徽章,儿童:利他主义者).

这是我的sql

SELECT *
FROM (`badge_types`)
LEFT JOIN `badges` ON `badges`.`badge_type` = `badge_types`.`badge_type_id`

这就是我得到的:

(
    [0] => stdClass Object
        (
            [badge_type_id] => 2
            [badge_type_title] => Participation Badges
            [badge_type_description] => Badges earning by participating in varIoUs areas of the site.
            [badge_type_order] => 2
            [badge_id] => 1
            [badge_name] => Autobiographer
            [badge_level] => 3
            [badge_requirement] => Completed all user profile fields
            [badge_type] => 2
            [badge_order] => 1
            [badge_sites] => 0
        )

    [1] => stdClass Object
        (
            [badge_type_id] => 1
            [badge_type_title] => Experience Badges
            [badge_type_description] => Badges earned by amount of experience gain throughout the site.
            [badge_type_order] => 1
            [badge_id] => 2
            [badge_name] => Apprentice
            [badge_level] => 3
            [badge_requirement] => Achieved 500 experience
            [badge_type] => 1
            [badge_order] => 1
            [badge_sites] => 0
        )

)

我怎么能把它变成:

array(
    array(
        [badge_type_id] => 2
        [badge_type_title] => Participation Badges
        [badge_type_description] => Badges earning by participating in varIoUs areas of the site.
        [badge_type_order] => 2
        [badges] => array(
            array(
                [badge_id] => 1
                [badge_name] => Autobiographer
                [badge_level] => 3
                [badge_requirement] => Completed all user profile fields
                [badge_type] => 2
                [badge_order] => 1
                [badge_sites] => 0
            ),
            array(
                [badge_id] => 2
                [badge_name] => Example 2
                [badge_level] => 3
                [badge_requirement] => blah bla
                [badge_type] => 2
                [badge_order] => 1
                [badge_sites] => 0
            )
        )
    ),
    array(
        [badge_type_id] => 1
        [badge_type_title] => Experience Badges
        [badge_type_description] => Badges earned by amount of experience gain throughout the site.
        [badge_type_order] => 1
        [badges] => array(
            array(
                [badge_id] => 2
                [badge_name] => Apprentice
                [badge_level] => 3
                [badge_requirement] => Achieved 500 experience
                [badge_type] => 1
                [badge_order] => 1
                [badge_sites] => 0
            ),
            array(
                [badge_id] => 2
                [badge_name] => Example 2
                [badge_level] => 3
                [badge_requirement] => Achieved 1000 experience
                [badge_type] => 1
                [badge_order] => 1
                [badge_sites] => 0
            )
        )
    )
)

我可以使用多个MySQL查询来完成它,但理想情况下我只想使用一个查询,如果可能的话?

解决方法:

使用SQL查询无法实现这一点,因为(由于关系模型性质)SQL查询将始终返回“平面”结果集而不进行任何嵌套(罕见的例外是供应商sql扩展,目标是生成XML输出或类似,但MysqL具有没有这样的扩展).

如果要从sql结果集中获取嵌套数组,则必须使用PHP代码对其进行后处理.可以将此代码组织为像对数组进行分组循环(使用sql分类),每次“内部”表的键更改时启动新组.这可以通过PHP以相当通用的方式完成,因此您可以编写一个这样的函数来对后处理许多SQL查询(给它适当的参数).

添加这是一个功能

function groupnest( $data, $groupkey, $nestname, $innerkey ) {
  $outer0 = array();
  $group = array(); $nested = array();

  foreach( $data as $row ) {
    $outer = array();
    while( list($k,$v) = each($row) ) {
      if( $k==$innerkey ) break;
      $outer[$k] = $v;
    }

    $inner = array( $innerkey => $v );
    while( list($k,$v) = each($row) ) {
      if( $k==$innerkey ) break;
      $inner[$k] = $v;
    }

    if( count($outer0) and $outer[$groupkey]!=$outer0[$groupkey] ) {
      $outer0[$nestname] = $group;
      $nested[] = $outer0;
      $group = array();
    }
    $outer0 = $outer;

    $group[] = $inner;
  }
  $outer[$nestname] = $group;
  $nested[] = $outer;

  return $nested;
}

data是要嵌套的数组(sql结果集),

groupkey是“外部”实体主键的列名,

nestname是将“内部行”放入其中的字段的名称,

innerkey是“内部”实体主键的列名.

在结果集中,“外部”实体的所有列必须在$innerkey列之前,并且“内部”实体的所有列必须遵循它.

要正确分组,结果集必须首先按来自“外部”实体的唯一表达式排序,例如按badge_type_title,badge_type_id,….的顺序排序.后面的字段将按顺序定义“内部”组内的排序.

要嵌套3个或更多实体的连接,您可以多次使用此功能(从内到外折叠“)

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐