2016-06-14 5 views
10

Jak uzyskać wartości z MySQL (5.6) kolumna jeśli zawiera dokument json jako ciągJak uzyskać wartości z MySQL (5.6) kolumna jeśli zawiera dokument json jako ciąg

Na przykład jeśli mamy tabelę - pracownika w tym mamy trzy coloumns id, nazwę i wykształcenie. i coloumn educations zawiera dane jako dokument json {"ug": "bsc", "pg": "mca", "ssc": "10th"} Potrzebuję wartości ug i pg z kolumny edukacyjnej

Czy możemy to zrobić za pomocą zapytań MySQL (5.6)?

+0

MySQL nie wie nic o danych JSON. Jest to po prostu spora ilość danych. Będziesz musiał zdekodować JSON * po * pobraniu go z bazy danych (używając dowolnego języka, którego używasz, aby uzyskać dostęp do bazy danych). –

+0

Wygląda na to, że MySQL 5.7 dodaje obsługę JSON: https://dev.mysql.com/doc/refman/5.7/en/json.html#json-paths –

Odpowiedz

13

Aby móc robić, co chcesz, potrzebujesz MySQL 5.7.8+. Ponieważ 5.7.8 można użyć JSON_EXTRACT funkcji, aby wyodrębnić wartość z ciągiem JSON:

SELECT JSON_EXTRACT('{"id": 14, "name": "Aztalan"}', '$.name'); 

+---------------------------------------------------------+ 
| JSON_EXTRACT('{"id": 14, "name": "Aztalan"}', '$.name') | 
+---------------------------------------------------------+ 
| "Aztalan"            | 
+---------------------------------------------------------+ 

Zrobione z here.

W MySQL 5.6 po prostu nie można uzyskać żądanej wartości, ponieważ MySQL nie wie nic o tym, czym jest obiekt JSON. Więc opcje są:

  • Upgrade do 5.7.8+
  • Analizować wynik kwerendy z czegoś, który obsługuje JSON:
8

W MySQL 5.6, przez def ault JSON_EXTRACT jest niedostępny domyślnie.
Jeśli nadal potrzebujesz dostępu do danych json w MySQL 5.6, musisz napisać funkcję niestandardową.

DELIMITER $$ 

DROP FUNCTION IF EXISTS `json_extract_c`$$ 

CREATE DEFINER=`root`@`%` FUNCTION `json_extract_c`(
    details TEXT, 
    required_field VARCHAR (255) 
) RETURNS TEXT CHARSET latin1 
BEGIN 
    RETURN TRIM(
    BOTH '"' FROM SUBSTRING_INDEX(
     SUBSTRING_INDEX(
     SUBSTRING_INDEX(
      details, 
      CONCAT(
      '"', 
      SUBSTRING_INDEX(required_field,'$.', - 1), 
      '"' 
     ), 
      - 1 
     ), 
     '",', 
     1 
    ), 
     ':', 
     - 1 
    ) 
) ; 
END$$ 

DELIMITER ; 

To pomoże. Stworzyłem go i przetestowałem.

+0

Wartość zwracana zawiera "}" na końcu plus podana: {"odległość": 55,62, "totalDistance": 11946.83} JSON_EXTRACT_C (atrybuty, "$ .distance") daje 11946.83} – user3631341

+0

sprawdź swoje dane, używam tej funkcji jako zamiennika z ostatnich kilku miesięcy bez ani jednego problem w ogóle. – rahulsm

+0

Czy możesz przetestować używając moich danych? – user3631341

3

odpowiedź Rahul nie wyszło całkiem dobrze dla mnie, więc mogę edytować go i to pracował dla mnie:

DELIMITER $$ 

DROP FUNCTION IF EXISTS `json_extract_c`$$ 

CREATE FUNCTION `json_extract_c`(
details TEXT, 
required_field VARCHAR (255) 
) RETURNS TEXT CHARSET latin1 
BEGIN 
SET details = SUBSTRING_INDEX(details, "{", -1); 
SET details = SUBSTRING_INDEX(details, "}", 1); 
RETURN TRIM(
    BOTH '"' FROM SUBSTRING_INDEX(
     SUBSTRING_INDEX(
      SUBSTRING_INDEX(
       details, 
       CONCAT(
        '"', 
        SUBSTRING_INDEX(required_field,'$.', - 1), 
        '":' 
       ), 
       - 1 
      ), 
      ',"', 
      1 
     ), 
     ':', 
     -1 
    ) 
) ; 
END$$ 

DELIMITER ; 
2

Oba poprzednie odpowiedzi nie działa na mnie, gdy element nie został wymieniony w tekście JSON . Moja ulepszona funkcja:

DELIMITER $$ 

DROP FUNCTION IF EXISTS `json_extract_c`$$ 

CREATE FUNCTION `json_extract_c`(
details TEXT, 
required_field VARCHAR (255) 
) RETURNS TEXT CHARSET latin1 
BEGIN 
    DECLARE search_term TEXT; 
    SET details = SUBSTRING_INDEX(details, "{", -1); 
    SET details = SUBSTRING_INDEX(details, "}", 1); 
    SET search_term = CONCAT('"', SUBSTRING_INDEX(required_field,'$.', - 1), '"'); 
    IF INSTR(details, search_term) > 0 THEN 
    RETURN TRIM(
     BOTH '"' FROM SUBSTRING_INDEX(
     SUBSTRING_INDEX(
      SUBSTRING_INDEX(
      details, 
      search_term, 
      - 1 
     ), 
      ',"', 
      1 
     ), 
     ':', 
     -1 
    ) 
    ); 
    ELSE 
    RETURN NULL; 
    END IF; 
END$$ 

DELIMITER ; 
Powiązane problemy