从mysql字段

时间:2015-07-11 13:12:25

标签: mysql regex json group-by

我有一个包含行的表,其中一行有一个包含数据的字段

{"name":"Richard","lastname":null,"city":"Olavarria","cityId":null}

我想选择我所拥有的所有不同的“城市”价值观。仅使用mysql服务器。

有可能吗?我正在尝试这样的事情

SELECT id FROM table_name WHERE field_name REGEXP '"key_name":"([^"]*)key_word([^"]*)"';

但我无法使正则表达式工作

提前致谢

5 个答案:

答案 0 :(得分:10)

MySQL在5.7.7版本中支持JSON http://mysqlserverteam.com/json-labs-release-native-json-data-type-and-binary-format/ 您将能够使用jsn_extract函数有效地解析您的JSON字符串。

如果你有一个旧版本并且想要纯粹在mysql中解决它,那么我担心你必须将它作为一个字符串处理并从中减少它的值(只是正常的字符串函数或使用正则表达式) 这不优雅,但它会起作用

http://sqlfiddle.com/#!9/97cfd/14

SELECT
  DISTINCT(substring(jsonfield, locate('"city":',jsonfield)+8,
     locate('","', jsonfield, locate('"city":',jsonfield))-locate('"city":',jsonfield)-8)
  )
FROM
  ForgeRock

答案 1 :(得分:4)

我把它包装成一个存储函数,用于那些受限于MySQL< 5.7.7:

的函数
CREATE FUNCTION `json_extract_string`(
    p_json text,
    p_key text
) RETURNS varchar(40) CHARSET latin1
BEGIN
    SET @pattern = CONCAT('"', p_key, '":"');
    SET @start_i = LOCATE(@pattern, p_json) + CHAR_LENGTH(@pattern);
    if @start_i = CHAR_LENGTH(@pattern) then
        SET @end_i = 0;
    else
        SET @end_i = LOCATE('"', p_json, @start_i) - @start_i;
    end if;
    RETURN SUBSTR(p_json, @start_i, @end_i);
END

请注意,这只适用于字符串值,但比@DmitryK的答案更健壮,因为如果找不到键,它会返回一个空字符串,并且键可以在JSON字符串中的任何位置。

答案 2 :(得分:0)

请参阅MariaDB' Dynamic Columns

另外,在这个论坛搜索[mysql] [json];这个话题经常被讨论过。

答案 3 :(得分:0)

是的,您绝对可以使用mysql中的JSON_EXTRACT()函数。

让我们获取一个包含JSON的表(此处为表client_services):

+-----+-----------+--------------------------------------+
| id  | client_id | service_values                       |
+-----+-----------+------------+-------------------------+
| 100 |      1000 | { "quota": 1,"data_transfer":160000} |
| 101 |      1000 | { "quota": 2,"data_transfer":800000} |
| 102 |      1000 | { "quota": 3,"data_transfer":70000}  |
| 103 |      1001 | { "quota": 1,"data_transfer":97000}  |
| 104 |      1001 | { "quota": 2,"data_transfer":1760}   |
| 105 |      1002 | { "quota": 2,"data_transfer":1060}   |
+-----+-----------+--------------------------------------+

要选择每个JSON字段,请运行以下查询:

SELECT 
    id, client_id, 
    json_extract(service_values, '$.quota') AS quota,
    json_extract(service_values, '$.data_transfer') AS data_transfer
FROM client_services;

所以输出将是:

+-----+-----------+----------------------+
| id  | client_id | quota | data_transfer|
+-----+-----------+----------------------+
| 100 |      1000 |     1 |       160000 |
| 101 |      1000 |     2 |       800000 |
| 102 |      1000 |     3 |        70000 |
| 103 |      1001 |     1 |        97000 |
| 104 |      1001 |     2 |         1760 |
| 105 |      1002 |     2 |         1060 |
+-----+-----------+----------------------+

现在,如果您想说 DISTINCT 配额,请运行以下查询:

SELECT 
   distinct( JSON_EXTRACT(service_values, '$.quota')) AS quota
FROM client_services;

所以这将导致您想要的输出:

+-------+
| quota |
+-------+
|     1 |
|     2 |
|     3 |
+-------+

希望这会有所帮助!

答案 4 :(得分:-1)

这可能有点晚了,但是被接受的答案对我不起作用。我用SUBSTRING_INDEX达到了预期的效果。

SELECT 
    ID, SUBSTRING_INDEX(SUBSTRING_INDEX(JSON, '"mykey" : "', -1), '",', 1) MYKEY
FROM MY_TABLE;

希望这会有所帮助。