I have a table containing countries:
id country
------------
0 Monaco
1 Mongolia
2 Montenegro
3 Morocco
4 Mozambique
5 Myanmar
I have a sub query that looks like this.
(SELECT country FROM COUNTRIES WHERE id < 10) AS ´Trip´
I want to have that subquery to be formatted as a string like this:
'Monaco, Mongolia, Montenegro, Morocco, Mozambique, Myanmar'
Is that possible?
You can use the group_concat function:
SELECT group_concat(country, ', ') FROM countries WHERE id < 10
What Lukas said, but use the SEPARATOR for your ,'s
SELECT group_concat(country SEPARATOR ', ') FROM countries WHERE id < 10
This is useful if you want a ';' instead of a ','
Related
I would like to be able to return a single line when the name of some musics are the same or similar, as for example this case:
music with similar names
You can see that the names are the same with an extension like " - JP Ver." or something like that, I would like to be able to group them in one row with the first column incrementing the whole.
My current request to return these lines is as follows:
select count(id) number, name, sec_to_time(floor(sum(duration) / 1000)) time
from track
where user_id = 'value'
group by name, duration
order by number desc, time desc;
I would like to get a result like this
Thank you for reading and responding! I wish you all a good day!
Try:
SELECT COUNT(name) no,
TRIM(SUBSTRING_INDEX(name, '-', 1)) namee
FROM track
GROUP BY namee
Example: https://onecompiler.com/mysql/3xt3bfev6
Use GROUP_CONCAT
Here is a proof of concept script. You can add your other columns. I have grouped by the first 4 letters. You will probably want to use more.
CREATE TABLE track (
idd INT,
nam CHAR(50),
tim INT
);
INSERT INTO track VALUES (1,'Abba 1',5);
INSERT INTO track VALUES (2,'Abba 2',6);
INSERT INTO track VALUES (3,'Beta 1',12);
INSERT INTO track VALUES (4,'Beta 4',8);
SELECT
LEFT(nam,4) AS 'Group',
COUNT(idd) AS 'Number',
GROUP_CONCAT(DISTINCT idd ORDER BY idd ASC SEPARATOR ' & ') AS IDs,
GROUP_CONCAT(DISTINCT nam ORDER BY nam ASC SEPARATOR ', ') AS 'track names',
SUM(tim) AS 'total time'
FROM track
GROUP BY LEFT(nam,4);
DROP TABLE track;
Output
Group Number IDs track names total time
Abba 2 1 & 2 Abba 1, Abba 2 11
Beta 2 3 & 4 Beta 1, Beta 4 20
I need to sort alphabetical but with numbers, but then alphabetical again???
If I do this...
ORDER BY name ASC
I get this...
2d this 10
2d this 9
this item
but I want this...
2d this 9
2d this 10
this item
so far I've done this...
ORDER BY CAST(name AS UNSIGNED) ASC
which gives me this...
this item
2d this 9
2d this 10
so it gets the d1 this 9 and d1 this 10 correct, but I need this item at the end.
I have been keeping it this way, then when looping through the results just check for this item, storing it and adding it to the results after the loop is finished, but is there any way to do it all within the sql query?
You can replace the numbers at the end of the string and use that for the first key in order by:
order by regexp_replace(name, '[0-9]*$', ''),
length(name),
name
In earlier versions of MySQL, you can remove the last numbers with a bit more pain:
order by (case when name regexp ' [0-9]+$'
then left(name, length(name) - instr(reverse(name), ' '))
else name
end),
length(name),
name
Here is a db<>fiddle.
For this sample data you can use the function substring_index():
select name
from tablename
order by substring_index(name, ' ', -1) + 0 = 0,
substring_index(name, ' ', -1) + 0,
name
See the demo.
Results:
| name |
| ---------- |
| 2a this 9 |
| 2a this 10 |
| this item |
I'm trying to select Ids from a table if they were found by a query on another table (my final goal is to delete, from second table, rows with ids in the first query). Here are my attempts:
SELECT #MyList:=GROUP_CONCAT(Id SEPARATOR ', ') AS MyList
FROM myitems
WHERE MyString IS NULL OR MyString = '';
So #MyList contains '41, 42, 49, 51'
Query based on FIND_IN_SET returns only one row
SELECT Id
FROM myitems2
WHERE FIND_IN_SET(Id, #MyList) > 0;
Expected Result:
41
42
Returns
41
I get the same result if I use IN:
SELECT Id
FROM myitems2
WHERE Id IN (#MyList);
I also tryed a query based on LOCATE, but it returns Ids not in the set:
SELECT Id
FROM myitems2
WHERE LOCATE(Id, #MyList) > 0;
Expected Result:
41
42
Returns
1
2
4
5
9
41
42
How can I fix my queries?
FIND_IN_SET doesn't works because you have spaces after commas.
Replace :
GROUP_CONCAT(Id SEPARATOR ', ')
By :
GROUP_CONCAT(Id SEPARATOR ',')
Or you can do :
SELECT Id
FROM myitems2
WHERE FIND_IN_SET(Id, replace(#MyList, ' ', ''));
I have a database field "name" that contains both first name and last name of the user.
For Example:
id name
1 Martha Ron
2 Ryan Knapp
3 John Mithchell
4 Scott Mathews
5 Dean Johns
.....
.....
How can i get all users order by last name?
Note: I can not create a another field in the database as it is a production database.
Try this SUBSTRING_INDEX
SELECT
* FROM `table`
ORDER BY
SUBSTRING_INDEX(`name`, ' ', -1);
See fiddle demo
Try this ... ref http://dev.mysql.com/doc/refman/5.0/en/string-functions.html#function_substring-index
SELECT *, SUBSTRING_INDEX(`name`, ' ', -1) as sortname
from tablename order sortname;
I want to count string separators from a MySQL query, mean if the field value is
like :-
1,2,3,4,5
as the string is comma separated so the separator count will be 4.
any idea then please share
THANKS,
you can try to count the length of string and minus the length of string without commas as follows:
LENGTH('1,2,3,4,5') - LENGTH(REPLACE('1,2,3,4,5', ',', ''))
select length('1,2,3,4,5') - length(replace('1,2,3,4,5', ',', ''))
I suggest the following design :
Table name : USER_HOBBIES
| USER_ID | HOBBY_ID |
1 1
1 2
1 3
2 2
2 4
2 5
And now you can easily count user hobbies for a given user :
SELECT count(*) FROM USER_HOBBIES WHERE USER_ID = <user-id>
although it requires another table it is much clearer and on a long list of hobbies this will be much faster than using a function for manipulating strings.