MySql query that aggregate and separe with comma - mysql

I need to do a query that return all my contact name separeted by comma's when they belong the same Group. I know how to do this in SQL Server using STUFF function, but how can I do the same in MySQL ?
Table: Group
Group_Id Description
1 New Group
2 Birthday
Table: Contacts
ID Name Surname Group_Id
1 Charlan Alves 1
2 Lucas Germano 2
3 Junior dos Santos 1
What I Expect
Group_Id Name
1 Charlan Alves, Junior dos Santos
2 Lucas Germano

Use GROUP_CONCAT():
SELECT
Group_Id,
GROUP_CONCAT(CONCAT(Name, ' ', Surname)) AS group_name
FROM
Contacts
GROUP BY
Group_Id
Note, that default separator is , (without space after comma). You may wish to add space after comma by specifying SEPARATOR ', '

Related

MySQL substring_index Delete Everything In Field After Space

I have a table called subscribers with a name field that contains data like this:
Tom Jones
Drew Brees
Tom Brady III
I need to delete everything after the first space for each record so that it looks like:
Tom
Drew
Tom
Using this question, I assembled the following query:
select substring_index(name,' ',1) as deleteAllAfterSpace from subscribers
I get the following error:
Current selection does not contain a unique column.
When I run:
SELECT * FROM subscribers WHERE INSTR(name, ' ') > 0
I do get the values I'm looking for as described.
I can assure you, name column is unique? What am I doing wrong?
SELECT name, subString(name, 1, POSITION(' ' IN name)) as deleteAllAfterSpace
FROM subscribers;
Here is all you n

How to select column name and values both to display on a page?

I want to select a value from a row and want to display only such values where there is a value with column name
----------------
id name gender
---------------
1 Bob M
2 Anny
3 Harry M
so I want to display 2 Anny with Id and gender only, that means if I select 1 there should be id, name, gender.
I am unable to figure out how to write code statement
IF my understanding is correct, You wanted to Select the name and Gender only when you search the id? is that right?
If that so:
Please try this
SELECT id, gender FROM [your_table] WHERE id = 2
EDIT
As I have said on the comment section, Please see this as reference.
SELECT IIF(gender IS NULL , name , name & ' ' & gender) AS Info FROM [your_table]
You want to display 2 Anny with Id and gender only. concat() function will help you for this
select concat(id,' ',name) as name , gender from table_name where id=2

Saving a COUNT column appearance while printing each row in the table

So there is a question I have not been able to find an answer to. Say you want to print each row in a table like the following:
ID | Name | Location
----+------+----------
1 | Adam | New York
2 | Eva | London
3 | Jon | New York
which would give the result
1 Adam New York
2 Eva London
3 Jon New York
Say that I at the same time would like to count the number of occurrences someone lives in a specific city, and save that value for printing after I've iterated through the table; is that possible? For example, printing the following:
1 Adam New York
2 Eva London
3 Jon New York
Inhabitants in New York: 2
Inhabitants in London: 1
Is this possible or would you have to iterate through the entire table twice by grouping by Location the second time, and counting those?
EDIT:
To clarify, I know I can solve it by calling:
SELECT * FROM table;
SELECT CONCAT('Inhabitants in ', Location, ': ', COUNT(ID))
FROM table
GROUP BY Location;
But now I am iterating through it twice. Is it possible to do it in only one iteration?
Generally speaking, yes, displaying every row from the table and displaying aggregated data is two separate tasks which should be handled by application, not by the database.
You have the option to run two queries - a plain select * from T, and select location, count(*) from T group by location, and displaying results sequentially. You also have the option to run only a select * from T one, and count the rows within your application, since you're displaying all rows anyway: use any dictionary-like structure your app language provides, with location string for key and running total integer for value.
If you're keen on keeping it a single query, check out WITH ROLLUP clause - https://dev.mysql.com/doc/refman/8.0/en/group-by-modifiers.html. This would certainly be an unusual way of using it, but if you group by location, id and then tamper with results a little, you can get what you want.
select if(id is null, CONCAT('Inhabitants in ', location, ': ', cnt), concat(id, ' ', name, ' ', location))
from
(
select id, location, name, count(*) cnt
from t
where location is not null
group by location, id with rollup
) q
where location is not null
order by id is null, id asc;
Though the performance could be questionable, compared to two plain queries; you should experiment or check with EXPLAIN.
Try below query, use subquery
select concat(concat(concat('Inhabitants in ',location),':'),total)
from
(select location, count(id) total
from tablename group by location)a

MySql: How to display only 1 name only per multiple name

To make it more clear, If I have this data in MySql:
name | allowance | age
----------------------
khan | 50 | 20
aal | 60 | 22
hyme | 50 | 21
khan | 61 | 20
notice that there are two 'khan' in the database with different allowance. I want to only show the name and the age but if I show it using the mysqli select statement, there would be two 'khan' but I only want to show only 1 'khan'. How can I do it?
You need to use GROUP_CONCAT to see agges of all Khans;
select name, GROUP_CONCAT(age) ages from Table group by name
or for minimum aged khan
select name , min(age) MiniumAge from Table group by name
or for elder khan
select name , max(age) MaxAge from Table group by name
or any khan
select name , age from Table group by name
.
Please try below query:-
SELECT name, age FROM table_name WHERE group by name
If you want any from multiple same record then simply used group by query.
I think you could do this:
SELECT name, age FROM table_name WHERE group by name,age
First thing: if both those "khan"s are the same person with two different allowances then your schema is not properly normalized and it will give you big troubles later - imagine you want to change "khan" to "Khan" - now you have to update it in multiple places instead once. Depending on your actual needs you may want one table of people (person_id, name, age), and table of allowances (person_id, allowance, [..some other parameters?..]).
Second, to really get what you want, either you use group by, to get one "random" row per each name as suggested in other answers, or you can do
SELECT DISTINCT name, age FROM table;
which will give you one row per each name-age combination, so khan-20 will be there only once - but if there were khan-25 then that is probably different person and you would have two khans returned, each with their own age.
You can try this mate:
SELECT DISTINCT
name, age
FROM
<your_table>;
or this one
SELECT
name, age
FROM
<your_table>
GROUP BY
name;
Q: Is there any chance that if there are 2 records of tha same name have difference value of age? If so, kindly update the question so that better answers will be given. Cheers!

How to correctly normalize data set in to tables?

I have a table where first column refers user name other columns refer each subjects that student does and their skill level for each subjects. These subjects are belong to several main subjects streams such as Mathematics, Art and etc.
I normalize the data in to following tables.
Subject_Stream
id Main_Stream Subject
1 Math pure-maths
2 Math applied-maths
3 Art Dancing
4 Art Music
Student_table
id name subject skill_level
1 xxx Music 5
2 xxx Pur-math 4
3 xxx Applied-math 1
4 yyy Music 3
select subjects, skill_level where usename="xxx" order by Desc
I can use a similar query to get subjects and their skill level for any given student.
Apart from, this I need to select students when I select any subject or collection of subjects that do.And print their Name, subjects, skill level in descending order.
Here any student can do different subjects in different streams too.
But I can't easily get this result from my existing tables. How to do this correctly?
Do I need to improve database schema?
First I want to suggest two small improvement for your table structure to better normalize the data. Your table Student_table would be slighly better organized if
instead of name you reference the user_id from your studends-table (that means the name of the student is only present in your studends-table - remember, names can change, p.e. marriage) and
instead of the name of the subject you reference the id of the subject - therefore the name of the subject is only present in your table Subject_Stream.
Your table Student_table would then look something like this:
id user_id subject_id skill_level
--------------------------------
1 1 4 5
2 1 1 4
3 1 2 1
4 2 4 3
Based on this you should be able to get every query you describe. For specifics please update your question and add some examples how your desired results look like, then I'll look into it and give you a few examples.
Apart from, this I need to select students when I select any subject
or collection of subjects that do. And print their Name, subjects,
skill level in descending order.
For a single subject . . .
select name, subject, skill_level
from Student_table
where subject = 'your subject name'
order by skill_level desc, name asc
For multiple subjects . . .
select name, subject, skill_level
from Student_table
where subject = 'some subject name'
or subject = 'some other subject name'
order by skill_level desc, name asc
There are other ways to express this kind of query, but I think multiple OR clauses is the easiest to understand at first.
To select by stream (Math, in this case) . . .
select Student_table.name
, Student_table.subject
, Student_table.skill_level
, subject_stream.main_stream
from Student_table
inner join subject_stream
on subject_stream.subject = student_table.subject
where subject_stream.main_stream = 'Math'
order by Student_table.skill_level desc, name asc