MySQL substring_index Delete Everything In Field After Space - mysql

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

Related

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

SQL query to get number of times a field repeats for another specific field

Let's say I have two fields in a table. For the purpose of discussion let's say the fields are first name and last name. I want to know how many times the first name shows up listed next to the same last name. Assuming the last name column is unique, how do I figure out how many times each first name exists for each last name?
i.e. let's say I have a table with the following data:
Smith, John
Smith, David
Smith, Jane
Smith, John
Smith, John
Black, John
Black, Jane
Black, Jack
Black, Samantha
Black, Jack
I want a result that tells me that for Smith, there are 3 Johns, 1 David and 1 Jane, and for Black, there are 2 Jacks, 1 Jane and 1 Samantha.
Not sure how to format the output best. Maybe simply:
Smith, John, 3, David, 1, Jane, 1
Black, Jack, 2, Jane, 1, Samantha, 1
Something that would allow me to easily output something like:
Smith: John (3), David (1), Jane (1)
Black: Jack (2), Jane (1), Samantha (1)
It's important to note that it's possible that the second field can repeat, so counting unique instances in the column is not useful. It's only useful in reference to the first field.
Thanks.
You can use a correlated sub-query in your SELECT statement and then wrap it all in a concat function to get the inline result you wanted
SELECT DISTINCT
CONCAT(LastName, ': ', FirstName, '(', (SELECT COUNT(FirstName) FROM Person WHERE FirstName = p.FirstName AND LastName = p.LastName),')')
FROM Person p
Simple aggregation?
select last_name, first_name, count(*)
from myTable
group by last_name, first_name
order by last_name, first_name
Displaying it in a Smith, John, 3, David, 1, Jane, 1 format will probably fail because there are way too many Smiths with way too many different last names.
My solution:
select name,surname, count(surname) over (partition by name) as cnt
from your_table
You can use this.
SELECT CONCAT( Name,':', GROUP_CONCAT(CONCAT( LastName, ' (', CNT , ')' ), ' ') )
FROM (
SELECT Name, LastName, COUNT(*) CNT FROM MyTable
GROUP BY
Name, LastName
) T
GROUP BY Name
Sql Fiddle
Result:
Black:Jane (1) ,John (1) ,Samantha (1) ,Jack (2)
Smith:David (1) ,Jane (1) ,John (3)

MySql query that aggregate and separe with comma

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 ', '

How to select all where column data begins with certain numbers in MySQL

This is my table:
studentID lastName firstName
08422567 Brown Susan
10356844 Black Roger
10659475 White Steven
09463729 Grey Naomi
I am trying to select all students whose ID begins with 10, so basically Roger and Steven.
Here are examples of what I was trying:
SELECT * FROM student WHERE studentID='10356844' AND studentID='10659475'
SELECT * FROM student WHERE studentID='10356844,10659475'
Would I need to use regular expressions for this, surely there must be a simpler way to run a query like this? In the future there may be 100 number beginning with 10, I cannot add all of these to a query, and the difficulty of this is why I ask this question here, in order to get the correct solution.
Not a regular expression, but WHERE studentID LIKE '10%'. The % is a wildcard, so it will match any student whose ID begins with 10.
This would never succeed:
SELECT * FROM student WHERE studentID='10356844' AND studentID='10659475'
because there is no row that has both of those values of studentID. It's impossible. What you meant to do was:
SELECT * FROM student WHERE studentID='10356844' OR studentID='10659475'

find out count of comma based value in MySql

I have two tables.
Table Emp
id name
1 Ajay
2 Amol
3 Sanjay
4 Vijay
Table Sports
Sport_name Played by
Cricket ^2^,^3^,^4^
Football ^1^,^3^
Vollyball ^4^,^1^
Now I want to write a query which will give me output like
name No_of_sports_played
Ajay 2
Amol 1
Sanjay 2
Vijay 2
So what will be Mysql query for this?
I agree with the above answers/comments that you are not using a database for what a database is for, but here is how you could calculate your table from your current structure in case you have no control over that:
SELECT Emp.name, IF(Played_by IS NULL,0,COUNT(*)) as Num_Sports
FROM Emp
LEFT JOIN Sports
ON Sports.Played_by RLIKE CONCAT('[[:<:]]',Emp.id,'[[:>:]]')
GROUP BY Emp.name;
See it in action here.
UPDATE: added the IF(Played_by IS NULL,0,COUNT(*)) instead of COUNT(*). This means that if an employee doesn't play anything they'll have a 0 as their Num_Sports. See it here (I also added in those ^ characters and it still works.
What it does is joins the Emp table to the Sports table if it can find the Emp.id in the corresponding Played_by column.
For example, if we wanted to see what sports Ajay played (id=1), we could do:
SELECT *
FROM Emp, Sports
WHERE Sports.Played_by LIKE '%1%'
AND Emp.id=1;
The query I gave as my solution is basically the query above, with a GROUP BY Emp.name to perform it for each employee.
The one modification is the use of RLIKE instead of LIKE.
I use RLIKE '[[:<:]]employeeid[[:>:]]' instead of LIKE '%employeeid%. The [[:<:]] symbols just mean "make sure the employeeid you match is a whole word".
This prevents (e.g.) Emp.id 1 matching the 1 in the Played_by of 3,4,11,2.
You do not want to store your relationships in a column like that. Create this table:
CREATE TABLE player_sports (player_id INTEGER NOT NULL, sport_id INTEGER NOT NULL, PRIMARY KEY(player_id, sport_id));
This assumes you have an id column in your sports table. So now a player will have one record in player_sports for each sport they play.
Your final query will be:
SELECT p.name, COUNT(ps.player_id)
FROM players p, player_sports ps
WHERE ps.player_id = p.id
GROUP BY p.name;