代码之家  ›  专栏  ›  技术社区  ›  tim

PHP:Best Practice/API函数,用于将SQL数据1:N整合到2d数组中

  •  0
  • tim  · 技术社区  · 4 年前

    我经常遇到这样一种情况:我有一个1:N关系,例如一个项目表和另一个表,每个项目都有额外的元数据/属性。

    考虑这个例子:

    users
    +-----------+-----------+
    | user_id   | username  |
    +-----------+-----------+
    | 1         |  max      |
    | 2         |  john     |
    | 3         |  elton    |
    | 4         |  tom      |
    | 5         |  dave     |
    +-----------+-----------+
    
    user_profile_data
    +-----+-----------+-----------+
    | uid | field_id  | field_val |
    +-----+-----------+-----------+
    |  1  | 1         |  a        |
    |  1  | 2         |  b        |
    |  2  | 1         |  c        |
    |  2  | 2         |  d        |
    |  3  | 1         |  e        |
    |  3  | 2         |  f        |
    |  3  | 3         |  g        |
    |  4  | 1         |  h        |
    |  4  | 4         |  i        |
    +-----+-----------+-----------+
    

    现在我有两个问题: 我想选择扩展用户数据,每个(uid,field_id)组合都是唯一的,通常我这样做:

    SELECT u.user_id, u.username, upd.field_id, upd.field_val
    FROM users u
    LEFT JOIN user_profile_data upd ON u.user_id = upd.uid
    

    我为每个用户/字段组合获得一行,需要在php中“重新排序”,因为通常我希望有一个数组,其中包含每个用户和扩展属性的子数组,例如:

    $users = array(1 => array('username' => max, 'data' => array(1 => 'a', 2 => 'b')), 2 => array('username' => 'john', ...));
    

    有没有一种标准化的方法来简化这一点,或者在这种情况下最好的做法是什么?PHP中已经有内置的东西了吗(不是外部SQL框架)?

    谢谢

    0 回复  |  直到 4 年前
        1
  •  1
  •   Armage    4 年前

    像这样的东西应该有用(没有测试,抱歉)

    $users = [];
    foreach($results as $result) { // assuming $results contains DB results
        if (!isset($users[$result['user_id']])) {
            $user[$result['user_id']] = [];
            $user[$result['user_id']]['username'] = $result['username'];
            $user[$result['user_id']]['data'] = [];
        }
        $user[$result['user_id']]['data'][$result['field_id']] = $result['field_val'];
    }
    

    这不是通用代码,应该针对每个表模式进行调整,但我不知道更简单的方法。或者,您通过不执行“加入”查询来垃圾邮件您的SQL server…:/(我觉得你的sql更好:))