Home > Software design >  Cannot display extra attributes in my query request
Cannot display extra attributes in my query request

Time:10-21

This is my little Salesman table I am working on:

 ------- -------------- -------- 
| empId | name         | gender |
 ------- -------------- -------- 
|     3 | Suresh Raina | M      |
|     5 | Andrew       | M      |
|     7 | Moeen        | F      |
|    11 | Moeen        | M      |
 ------- -------------- -------- 

What I have to display in my query is the following:

name       count
Andrew       1
Moeen        2 (7,Moeen,F)(11,Moeen,M)
Suresh Raina 1

If count has more than one matching name then it displays all the attributes.

I have the following query but it is not printing the ones that have a count higher than 1.

select all  name, count( name) AS totalNumber 
  from Salesman GROUP BY name HAVING COUNT(name)= 1 OR COUNT(name)>1 IN 
   ( select group_concat(empId ,name , gender) from Salesman group by name ) order by name asc;

Any hints or ideas you can share would be appreciated.

CodePudding user response:

Try this.

Query

select
  name,
  count(*) as count,
  case when count(*) < 2 then ''
  else
  concat('(',
    group_concat(
      concat_ws(',', empid, name, gender)
      separator '),('
    ),
    ')'
  )
  end as flds
from salesman
group by name

Result

name         | count | flds                    
:----------- | ----: | :-----------------------
Andrew       |     1 |                         
Moeen        |     2 | (7,Moeen,F),(11,Moeen,M)
Suresh Raina |     1 |                         

Example

https://dbfiddle.uk/?rdbms=mysql_5.7&fiddle=9a804f0ac1a7290af61ce3649670358c

Explanation

Start with this:

select name, count(*) as counter
from salesman
group by name

This gives you name and count. That's all good.

Now, you want to combine the fields. So, you could use concat_ws. The first parameter to that function will be the separator. We'll use ,. Then will be the list of fields.

So, concat_ws(',', name, gender) will return John,M or whatever the name in each row is. We'll take advantage of that.

Since we want to use concat_ws along with count(*), we need to do some kind of summarization of concat_ws. We do that with group_concat.

select name, count(*) as counter, group_concat(concat_ws(',', empid, name, gender))
from salesman
group by name

gives us

name         | counter | group_concat(concat_ws(',', empid, name, gender))
:----------- | ------: | :------------------------------------------------
Andrew       |       1 | 5,Andrew,M                                       
Moeen        |       2 | 7,Moeen,F,11,Moeen,M                             
Suresh Raina |       1 | 1,Suresh Raina,M                                 

Alright, we are closer. Now, we give group_concat a separator. That separates the records. We use the separate ),( so that the query becomes like this:

select name, count(*) as counter,
  group_concat(concat_ws(',', empid, name, gender) separator '),(')
from salesman
group by name

gives

> <pre>
> name         | counter | group_concat(concat_ws(',', empid, name, gender) separator '),(')
> :----------- | ------: | :----------------------------------------------------------------
> Andrew       |       1 | 5,Andrew,M                                                       
> Moeen        |       2 | 7,Moeen,F),(11,Moeen,M                                           
> Suresh Raina |       1 | 1,Suresh Raina,M                                                 
> </pre>

Even closer. All we have left is to add open and closed parenthesis around our group concat. Once we do that, we get a clean output.

However, we don't want Andrew and Suresh's information to be published because their count is 1. So, we put a case when ... else ... end statement.

  • Related