【问题标题】:Mysql to Json. Can this be solved using MySQL?Mysql 到 Json。这可以使用 MySQL 解决吗?
【发布时间】:2014-02-01 09:58:39
【问题描述】:

我有一个 MySQL 查询,它将被转换为 JSON 并在 Obj C 中用于每个具有特定 ID 的用户。我相信这是一个 MySQL 难题,但 JSON 中可能有答案。我不会问很多问题,所以我会尽量使其简洁。

这是一个用户值的屏幕截图。如果您注意到,field_id 可能会有所不同,因为并非所有信息都是必需的,因此对于给定的 user_id,id 字段的值将从 3 到 8 不等:

我必须查询结果 GROUP BY column1 (user_id),但只有 WHERE column2 (field_id) 具有以下值 field_id='18' 和 field='19',然后(大问题)我需要用 column3(值)的两个值填充一个 GROUP 中的结果,以便我可以在一个 JSON 对象中获得结果。

我已经知道如何转换为 JSON 以在 iOS 中使用,但我只能得到它以将结果作为两个对象提供给我。

我当前的查询

$query = "SELECT * FROM table1 WHERE field_id='18' OR field_id='19' ORDER BY user_id ";

当前结果

[{"id":"5","user_id":"461","field_id":"18","value":"1_MX4zNjcxNzM5Mn4x...","access":"0"},

{"id":"6","user_id":"461","field_id":"19","value":"T1==cGFydG5lcl9pZD0...","access":"0"},

{"id":"11","user_id":"463","field_id":"18","value":"1_MX4zNjcxNzM...","access":"0"},

{"id":"12","user_id":"463","field_id":"19","value":"T1==cGFydG5lcl9...","access":"0"}]

我需要将两个具有匹配 user_id 字段的 JSON 对象作为一个对象,其结果将 field='18' 值与 field='19' 值区分开来。比如:

    [{"id":"5","user_id":"461","field_id":"18","value18":"1_MX4zNjcxNzM5Mn4x...","value19":"T1==cGFydG5lcl9pZD0...","access":"0"},

{"id":"11","user_id":"463","field_id":"18","value18":"1_MX4zNjcxNzM...","value19":"T1==cGFydG5lcl9...","access":"0"}]  

    [{"id":"5","user_id":"461","field_id='18'":"1_MX4zNjcxNzM5Mn4x...","field='19'":"T1==cGFydG5lcl9pZD0...","access":"0"},

{"id":"11","user_id":"463","field_id='18'":"1_MX4zNjcxNzM...","field='19'":"T1==cGFydG5lcl9...","access":"0"}]  

谢谢...

【问题讨论】:

  • 检查mysql group_concat dev.mysql.com/doc/refman/5.0/en/…
  • +1 写得很好的问题
  • @AbhikChakraborty 我尝试使用 GROUP_CONCAT,正如 Kay Nelson 在下面建议的那样,略有承诺。但如您所见,GROUP BY 没有达到将 user_id 字段分组的预期结果,这是创建一个对象的主要目标......

标签: php mysql sql json


【解决方案1】:

您可能希望在读取结果集时考虑在 PHP 中处理此问题。

所以使用你当前的查询

SELECT * FROM table1 WHERE field_id='18' OR field_id='19' ORDER BY user_id

但是像这样构建结果数据对象:

$results = array();
$i = -1;
$current_user_id = '';
while ($row = [YOUR MySQL FETCH MECHANISM HERE]) {
    // determine if this record represents a new user id in the result set
    // if so, we need to set up the user object and start another entry in top level array  
    if($current_user_id != $row['user_id']) {
        // you have moved to a new user in the result set
        // increment your array counter and set current user id
        $i++; // will set value to 0 on first iteration
        $current_user_id = $row['user_id'];
        // build new array entry
        $results[$i] = new stdClass();
        $results[$i]->user_id = $current_user_id;
        $results[$i]->fields = array(); 
    }
    // build field object for insertion
    $field = new stdClass();
    $field->field_id = $row['field_id'];
    $field->value = $row['value'];
    $results[$i]->fields[] = $field;
}

在编码 $results 时,这将为您提供如下 JSON 结构:

[
  {
    "user_id":"461",
    "fields": [
      {
        "field_id":"18",
        "value":"foobar"
      },
      {
        "field_id":"19",
        "value":"abcxyz"
      }
    ]
  },
  ...
]

这种数据结构将比一些需要爆炸级联字段 id/value 字符串的解决方案更容易被消费应用程序使用。另请注意,我没有在数据结构的任何地方包含id 字段,因为它在这种情况下没有任何意义。如果您确实需要该 id,您可以将其作为另一个属性添加到 field 对象中,因为这是一对一的关系(而不是 user_id)。

根据您的评论,如果字段值已知并且您需要通过 field_id 索引访问它,您可以稍微修改我上面显示的内容以构建可索引的字段列表,而不是简单的对象数组:

$results = array();
$i = -1;
$current_user_id = '';
while ($row = [YOUR MySQL FETCH MECHANISM HERE]) {
    // determine if this record represents a new user id in the result set
    // if so, we need to set up the user object and start another entry in top level array  
    if($current_user_id != $row['user_id']) {
        // you have moved to a new user in the result set
        // increment your array counter and set current user id
        $i++; // will set value to 0 on first iteration
        $current_user_id = $row['user_id'];
        // build new array entry
        $results[$i] = new stdClass();
        $results[$i]->user_id = $current_user_id;
        $results[$i]->fields = array(); 
    }
    // insert field value at field_id index position
    $results[$i]->fields[$row['field_id']] = $row['value'];
}

这会给你一个像这样的 JSON 表示。

[
  {
    "user_id":"461",
    "fields": {
        "18":"foobar",
        "19":"abcxyz"
    }
  },
  ...
]

这将允许客户端根据字段 ID 轻松查找。当然,您可能需要考虑类似的 user_id。您可以从用户对象访问fields->18(或基于客户端语言语法的类似内容)。

【讨论】:

  • 感谢@mike,目前我的 $results 对象很简单:`$rows = array();而 ($r =mysql_fetch_assoc($result)) { $rows[] = $r; } 回声 json_encode($rows);' .我看到的问题是我仍然无法告诉 Obj C 我想要 field_id 1819 的 value 来自字段对象...
  • @insitemobile 好的。您可以简单地更改索引数据的方式。您可以让字段本身是对象/关联数组,而不是对象数组。请参阅更新的答案以进行简单更改。最重要的是,您可以在编码之前轻松地在 PHP 中构建您想要的数据,从而允许客户端应用程序更轻松地处理数据。
【解决方案2】:

我不能 100% 确定这是否可行。我不能轻易尝试它的 JSON 输出。但是,如果您运行这样的查询呢?

SELECT id, user_id,
GROUP_CONCAT(field_id,':',value) field_id,
access
FROM table1 WHERE field_id='18' OR field_id='19' 
GROUP BY user_id
ORDER BY user_id 

【讨论】:

  • 有点希望,查询确实设法对用户的 field_id 和值进行 GROUP_CONCAT,但仍然将 field_id 18 和 19 作为单独的对象:{"id":"5","user_id":" 461","field_id":"18:1_MX4zNjcxNz...","access":"0"},{"id":"6","user_id":"461","field_id":"19:T1 ==cGFydG5l...","access":"0"},
  • 如果您只尝试GROUP BY user_id 会怎样?
  • 我试过了,它只响应第一个值而没有其他值:{"id":"1","user_id":"461","field_id":"2", "value":"Male","access":"0"},{"id":"51","user_id":"462","field_id":"2","value":"Male", "访问":"0"}
  • 非常感谢@Kay Nelson,我才意识到我误解了你。我从 GROUP BY id, user_id 中删除了 idGROUP BY user_id ,当我弄清楚如何让iOS 知道我想要 field_id:18 和 field:19 的值。我希望它就像添加 :18 或 :19 一样简单。在这里:{"id":"5","user_id":"461","field_id":"18:1_MX4z...,19:T1==cG...","access":"0"}
  • 虽然GROUP_CONCAT() 当然可以为您提供将不同字段记录折叠为单个用户ID 的最低能力。这也产生了您的客户端应用程序需要了解如何处理串联字符串值的问题。我强烈建议您采取一种方法,在将数据编码为 JSON 之前,在 PHP 中更恰当地构造数据,以便消费客户端以更可用的格式获取数据。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-02-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-02-07
相关资源
最近更新 更多