2012-09-20 7 views
21

Jak utworzyć format json z mysql group-concat?Jak utworzyć format json z mysql group-concat?

(używam MySQL)

Przykład 1:

tabela1:

email   | name | phone 
------------------------------------- 
[email protected] | Ben  | 6555333 
[email protected] | Tom  | 2322452 
[email protected] | Dan  | 8768768 
[email protected] | Joi  | 3434356 

jak kod składni, które nie dają mi format:

select email, group-concat(name,phone) as list from table1 group by email

wyjście że potrzeba:

email   | list 
------------------------------------------------ 
[email protected] | {name:"Ben",phone:"6555333"},{name:"Joi",phone:"3434356"} 
[email protected] | {name:"Tom",phone:"2322452"},{name:"Dan",phone:"8768768"} 

Dzięki

+1

Jeśli baza danych będzie się rozwijać, jest to zły pomysł. Lepiej rób to, używając kodu w swojej aplikacji. –

+0

db static dla tylko jednoczęściowego – Yosef

Odpowiedz

35

Spróbuj zapytanie -

SELECT 
    email, 
    GROUP_CONCAT(CONCAT('{name:"', name, '", phone:"',phone,'"}')) list 
FROM 
    table1 
GROUP BY 
    email; 

formacie JSON wynik -

+---------------+-------------------------------------------------------------+ 
| email   | list              | 
+---------------+-------------------------------------------------------------+ 
| [email protected] | {name:"Ben", phone:"6555333"},{name:"Joi", phone:"3434356"} | 
| [email protected] | {name:"Tom", phone:"2322452"},{name:"Dan", phone:"8768768"} | 
+---------------+-------------------------------------------------------------+ 
+0

bardzo dziękuje – Yosef

+3

co by się stało, gdyby nazwa zawierała podwójny cudzysłów? – K2xL

+0

To zależy od trybu ANSI_QUOTES SQL, jeśli jest on aktywowany - wtedy powinieneś podwoić "w nazwach, inne - to zadziała." – Devart

1

Zastosowanie jak ten

SELECT email,concat('{name:"',ur_name_column,'",phone:"',ur_phone_column,'"}') as list FROM table1 GROUP BY email; 

Pozdrowienia

10

Odpowiedź Devarta powyżej jest świetna, ale pytanie K2xL jest poprawne. Odpowiedź, którą znalazłem, polega na kodowaniu w szesnastkowym kolumnie nazwy za pomocą funkcji HEX(), która zapewnia utworzenie prawidłowego JSON. Następnie w aplikacji zamień szesnastkowy z powrotem na ciąg.

(Przepraszamy za autopromocji, ale) Pisałem trochę blogu o tym z nieco bardziej szczegółowo: http://www.alexkorn.com/blog/2015/05/hand-rolling-valid-json-in-mysql-using-group_concat/

[Edycja dla Oriol] Oto przykład:

SELECT email, 
    CONCAT(
     '[', 
     COALESCE(
      GROUP_CONCAT(
       CONCAT(
        '{', 
        'name: \"', HEX(name), '\", ', 
        'phone: \"', HEX(phone), '\"', 
        '}') 
       ORDER BY name ASC 
       SEPARATOR ','), 
      ''), 
     ']') AS bData 
FROM table 
GROUP BY email 

Zauważ też, że dodałem COALESCE na wypadek, gdyby nie było żadnych przedmiotów dla tego e-maila.

+0

cóż, to jest rozwiązanie, dziękuję! – serkan

+0

Dodaj złożony przykład konkatencji, myślę, że to bardzo pomocne ;-) – Oriol

+0

Rozwiązało to mój problem, inne rozwiązania zawiodły podczas dekodowania wynikowego jsona z nieprawidłowymi znakami takimi jak karty, ukośniki, ... – Mirko

18

Z nowszych wersji MySQL, można użyć funkcji JSON_OBJECT do osiągnięcia pożądanego rezultatu, tak:

GROUP_CONCAT(
    JSON_OBJECT(
    'name', name, 
    'phone', phone 
) 
) AS list 

nadzieję, że pomoże.

0

Odejście od odpowiedzi @ Devarta ... jeśli pole zawiera rozłamy liniowe lub podwójne cudzysłowy, wynik nie będzie prawidłowy JSON.

Tak więc, jeśli wiemy, że „telefon” field okazjonalnie zawiera podwójne cytaty i linebreaks nasza SQL wyglądałby następująco:

SELECT 
    email, 
    CONCAT(
    '[', 
    GROUP_CONCAT(CONCAT(
     '{name:"', 
     name, 
     '", phone:"', 
     REPLACE(REPLACE(phone, '"', '\\\\"'),'\n','\\\\n'), 
     '"}' 
    )), 
    ']' 
) AS list 
FROM table1 GROUP BY email;

Jeśli Ben telefon ma cytatów w środku, a Joi zawiera nowa linia, SQL dałby (ważne JSON) wyniki takie jak:

[{name:"Ben", phone:"655\"5333"},{name:"Joi", phone:"343\n4356"}]