Display comma separated results with Mysql

Asked

Viewed 1,758 times

1

administrador  | regiao
bruno          | 2,3,4
pedro          | 1
jose           | 5,7

I have an administrator table and a region table, where 1 administrator can manage a region or several. I want to make a query that brings me the name of the regions that each administrator is responsible separating by commas. Ex:

administrador  | regiao
bruno          | São Paulo, Belo Horizonte, Sorocaba
pedro          | Boituva
jose           | Rio de Janeiro, Resende

How to make this consultation?

3 answers

5

I made a fiddle to validate, taking advantage of the idea of group_concat from the @fernandosavio response:

select a.nomeAdm as nome,
       GROUP_CONCAT(DISTINCT r.nomeREg SEPARATOR ", ") as regiao
  from regiao r
 inner join administrador a on r.idAdm = a.idAdm
 group by r.idAdm, a.nomeAdm

Here the fiddle: http://sqlfiddle.com/#! 9/06be20/8

2


Then better understand the problem here are my thoughts and possible solutions.

Solution 1:

The best idea would be to restructure the tables with Foreign Keys. N-1 if areas can only have one administrator. N-N if an area can have multiple administrators and each administrator can manage multiple areas.

If option N-1 is chosen, the @Ricardo-punctual response is exactly what you need. Since the table regions have a foreign key for the table administrators.

Ad-hoc response for reference:

SELECT 
    a.nomeAdm as nome,
    GROUP_CONCAT(DISTINCT r.nomeREg SEPARATOR ", ") as regiao
FROM regiao r
INNER JOIN administrador a ON r.idAdm = a.idAdm
GROUP BY r.idAdm;

If N-N is the need, I keep the previous answer which is to have a pivot table with foreign keys for regions and administrators.

SELECT
    a.nome as administrador,
    GROUP_CONCAT(DISTINCT r.nome SEPARATOR ", ") as regioes
FROM administradores as a
INNER JOIN adm_regioes AS ar ON ar.adm_id = a.id
INNER JOIN regioes AS r ON ar.regiao_id = r.id
GROUP BY a.id;

Solution 2:

If it is not possible to restructure the tables, it is possible to make a Join using REGEXP so that the DBMS recognizes the field regions and can reference the table regions.

An example would be:

SELECT
    a.nome as nome,
    a.regions as regions,
    GROUP_CONCAT(DISTINCT r.nome SEPARATOR ', ') as regions_concat
FROM administrators as a
INNER JOIN regions as r
    ON a.regions REGEXP CONCAT("[[:<:]]", r.id, "[[:>:]]")
GROUP BY a.id;

Upshot:

+-------+---------+----------------------+
| nome  | regions |    regions_concat    |
+-------+---------+----------------------+
| Pedro |       1 | Sao paulo            |
| João  |     2,3 | Campinas, Manaus     |
| José  |     4,5 | Campo Grande, Santos |
+-------+---------+----------------------+

The INNER JOIN would be done by applying the REGEXP in the column where the symbols [[:<:]] and [[:>:]] are the word boundaries (equivalent to \b in other REGEXP engines).

In this way your problem is solved, but it should be pointed out that it is not ideal and also not at all performatic.

See working on Dbfiddle

PS: You need to test if it works normally with two or more digit numbers as well.


These are the options I see without having to deal with at the application level. I hope it helps.

  • I think if you run in the same select, it will duplicate the name of the administrator...

  • I’ll update with DISTINCT then.

  • It’s not an N-N, I only have two tables, the Administrator and the Region table....

  • Sorry @Daywisonferreiraleal... better answer.

0

select admin.name,
       GROUP_CONCAT(DISTINCT r.name SEPARATOR ", ") as regiao
  from regions r
 inner join administrator admin on r.id = admin.regions
 group by r.id, admin.name order by admin.id desc

The result of the above query was:

name | regiao
pedro| sao paulo
joao | manaus
jose | campo grande

When it really should be:

name | regiao
pedro| sao paulo
joao | manaus, campinas
jose | campo grande, santos

The query is not making the concatenations, only this considering the first region. Remembering that the tables are like this :

Regions
id | name
1  | Sao paulo
2  | Manaus
3  | Campinas
4  | Campo Grande
5  | Santos

Administrator
id | name | regions
1  | pedro| 1
2  | joao | 2,3
3  | jose | 4,5
  • In your query you are grouping by region and by administrator, when apparently you want to group only by administrator. r.id, of GROUP BY your query will make more sense, logically speaking. The real problem is breaking the field regions within the SELECT to use in the WHERE

  • I’ve already removed the r. id GROUP BY but it still does not concatenate the regions of each administrator..

  • I suppose the countryside administrator.regions is VARCHAR. If this is the case, Mysql is converting the field to an integer and therefore does not see the other regions. Because when it converts "1,2,3" to INTEGER the converted value is 1.

  • The @Ricardo-punctual response would be the correct way to make this ratio 1-N.

  • @fernandosavio the field Regions is varchar even, I just saw here in the table.

  • Some solution?

  • I updated my answer. If you cannot change the field structure you will have to use REGEXP in JOIN even.

  • My problem was solved using REGEXP, as mentioned in your solution

Show 3 more comments

Browser other questions tagged

You are not signed in. Login or sign up in order to post.