I have to add two or more strings from MySQL database, for this I used CONCAT() function.
Here is the first table classes which stores PHP classes.
class_id class_name
-------- ----------
1 accountant
2 attendance
Another table methods which stores each class methods.
class_id method_name
-------- -----------------------
1 __construct
1 add_expenses
2 __construct
2 attendance_report
And I write the query for concatenation.
SELECT
`cc`.`class_id`,
`cc`.`class_name`,
CONCAT(`cm`.`method_name`, ',') AS `method_name`
FROM
`classes` AS `cc`
LEFT JOIN `methods` AS `cm`
ON `cm`.`class_id` = `cc`.`class_id`
GROUP BY `cc`.`class_name`;
Which is not working. My expected output is
class_id class_name method_name
-------- -------------- ------------
1 accountant __construct, add_expenses, .... n
2 attendance __construct, attendance_report, .... n
Any ideas?
Use
GROUP_CONCAT
instead of
CONCAT
GROUP_CONCAT(cm.method_name) you do not needs to pass comma as separator that will be taken default.
Related
I have a database table called 'Customers' like this:
Sl Name Profession
1 ABC Doctor
2 QWE Engineer
3 ERT null
4 DEF Doctor
5 JGJ null
I want to order this table as all the names with professions are at the beginning and names without profession(null) at the bottom, like this:
Sl Name Profession
1 ABC Doctor
2 QWE Engineer
4 DEF Doctor
5 JGJ null
3 ERT null
Is there any query to do this? Thanks in advance..
NULLs in MySQL (and most flavors of SQL) sort first by default, not last. One general way to force NULL values to the bottom is to use a CASE or IF expression:
SELECT
Sl, Name, Profession
FROM yourTable
ORDER BY
IF(Profession IS NOT NULL, 0, 1),
Sl;
use order by
select * from table_name
order by case when Profession is not null then 1 else 2 end
NO DB engine provide you order rows without using order by
I'm trying to create a query that lists staffID, staffName and staffDOB, but only of staff that first and last names begin with the same letter. So I have both staffFirst and staffLast as individual columns, will join them together. I will not be customising staffID and staffDOB. I would like it to return the name of staff like adam apple = a apple, so the output would look like:
staffID | staffName | staffDOB
------------------------------
1 | A Apple | 12/10/99
.... | .... | ....
All columns are in the same table "N_Staff". I am using HeidiSQL which I believe uses MySQL. I know how to grab the data of each column, though it is selecting the first letters of both first and last names and comparing them which is confusing me as it is not an specific letter I am looking for but any letter that is common on both tables of index [0].
Thus far:
SELECT staffID FROM N_Staff,
SELECT staffFirst, staffLast AS staffName
FROM N_Staff WHERE ... , --perhaps should be using LEFT ?
SELECT staffDOB from N_Staff;
How about:
SELECT staffID, CONCAT(LEFT(staffFirst,1), ' ', staffLast) AS staffName, staffDOB
FROM N_Staff
WHERE LEFT(staffFirst,1) = LEFT(staffLast,1)
use this:
SELECT * FROM NS_WORDS;
mani
nikhil
sugandh
mining
_lkdnsad
_lkdndsadnjas
_lk
_ja
_ls
_lsa
nikhil nikhil
nikhil name
SELECT * FROM NS_WORDS
where not( to_char(SUBSTR(a,1,1))=to_char(substr(a,instr(a,' ',1,1),1)));
output:
nikhil nikhil
nikhil name
your where will go like:
where not( to_char(SUBSTR(staffName ,1,1))=to_char(substr(staffName
,instr(staffName ,' ',1,1),1)));
I have this query :
select
name
from
provinces
WHERE
province_id IN(1,3,2,1)
ORDER BY FIELD(province_id, 1,3,2,1)
the Number of values in IN() are dynamic
How can I get all rows even duplicates ( in this example -> 1 ) with given ORDER BY ?
the result should be like this :
name1
name3
name2
name1
plus I shouldn't use UNION ALL :
select * from provinces WHERE province_id=1
UNION ALL
select * from provinces WHERE province_id=3
UNION ALL
select * from provinces WHERE province_id=2
UNION ALL
select * from provinces WHERE province_id=1
You need a helper table here. On SQL Server that can be something like:
SELECT name
FROM (Values (1),(3),(2),(1)) As list (id) --< List of values to join to as a table
INNER JOIN provinces ON province_id = list.id
Update: In MySQL Split Comma Separated String Into Temp Table can be used to split string parameter into a helper table.
To get the same row more than once you need to join in another table. I suggest to create, only once(!), a helper table. This table will just contain a series of natural numbers (1, 2, 3, 4, ... etc). Such a table can be useful for many other purposes.
Here is the script to create it:
create table seq (num int);
insert into seq values (1),(2),(3),(4),(5),(6),(7),(8);
insert into seq select num+8 from seq;
insert into seq select num+16 from seq;
insert into seq select num+32 from seq;
insert into seq select num+64 from seq;
/* continue doubling the number of records until you feel you have enough */
For the task at hand it is not necessary to add many records, as you only need to make sure you never have more repetitions in your in condition than in the above seq table. I guess 128 will be good enough, but feel free to double the number of records a few times more.
Once you have the above, you can write queries like this:
select province_id,
name,
#pos := instr(#in2 := insert(#in2, #pos+1, 1, '#'),
concat(',',province_id,',')) ord
from (select #in := '0,1,2,3,1,0', #in2 := #in, #pos := 10000) init
inner join provinces
on find_in_set(province_id, #in)
inner join seq
on num <= length(replace(#in, concat(',',province_id,','),
concat(',+',province_id,',')))-length(#in)
order by ord asc
Output for the sample data and sample in list:
| province_id | name | ord |
|-------------|--------|-----|
| 1 | name 1 | 2 |
| 2 | name 2 | 4 |
| 3 | name 3 | 6 |
| 1 | name 1 | 8 |
SQL Fiddle
How it works
You need to put the list of values in the assignment to the variable #in. For it to work, every valid id must be wrapped between commas, so that is why there is a dummy zero at the start and the end.
By joining in the seq table the result set can grow. The number of records joined in from seq for a particular provinces record is equal to the number of occurrences of the corresponding province_id in the list #in.
There is no out-of-the-box function to count the number of such occurrences, so the expression at the right of num <= may look a bit complex. But it just adds a character for every match in #in and checks how much the length grows by that action. That growth is the number of occurrences.
In the select clause the position of the province_id in the #in list is returned and used to order the result set, so it corresponds to the order in the #in list. In fact, the position is taken with reference to #in2, which is a copy of #in, but is allowed to change:
While this #pos is being calculated, the number at the previous found #pos in #in2 is destroyed with a # character, so the same province_id cannot be found again at the same position.
Its unclear exactly what you are wanting, but here's why its not working the way you want. The IN keyword is shorthand for creating a statement like ....Where province_id = 1 OR province_id = 2 OR province_id = 3 OR province_id = 1. Since province_id = 1 is evaluated as true at the beginning of that statement, it doesn't matter that it is included again later, it is already true. This has no bearing on whether the result returns a duplicate.
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.
Got this:
Table a
ID RelatedBs
1 NULL
2 NULL
Table b
AID ID
1 1
1 2
1 3
2 4
2 5
2 6
Need Table a to have a comma separated list as given in table b. And then table b will become obsolete:
Table a
ID RelatedBs
1 1,2,3
2 4,5,6
This does not rund through all records, but just ad one 'b' to 'table a'
UPDATE a, b
SET relatedbs = CONCAT(relatedbs,',',b.id)
WHERE a.id = b.aid
UPDATE: Thanks, 3 correct answers (marked oldest as answer)! GROUP_CONCAT is the one to use. No need to insert commas between the ids using relatedids = CONCAT(relatedids,',',next_id) that is done automatic by GROUP_CONCAT.
You'll have to use the mysql group_concat function in order to achieve this: http://dev.mysql.com/doc/refman/5.1/en/group-by-functions.html#function_group-concat
Look into GROUP_CONCAT(expr)
mysql> SELECT student_name,
-> GROUP_CONCAT(DISTINCT test_score
-> ORDER BY test_score DESC SEPARATOR " ")
-> FROM student
-> GROUP BY student_name;
You can't do that in standard SQL. You could write a stored procedure to do that. I had a similar problem, but I was using PostgreSQL so I was able to resolve it by writing a custom aggregate function so that you can do queries like
select aid, concat(id)
from b group by
aid
Update: MySQL has a group_concat aggregate function so you can do something like
SELECT id,GROUP_CONCAT(client_id) FROM services WHERE id = 3 GROUP BY id
as outlined here.