how to get duplicate column values in comma separated [duplicate] - mysql

This question already has answers here:
Can I concatenate multiple MySQL rows into one field?
(16 answers)
Closed 8 years ago.
I have a table like this
+----+------------+------------+---------+-----+------+------+
| id | is_deleted | sort_order | version | cid | pid | qid |
+----+------------+------------+---------+-----+------+------+
| 1 | | 1 | 0 | 1 | 1 | 1 |
| 2 | | 2 | 0 | 1 | 1 | 2 |
| 3 | | 3 | 0 | 1 | 1 | 3 |
| 4 | | 1 | 0 | 1 | 2 | 7 |
| 5 | | 2 | 0 | 1 | 2 | 1 |
| 6 | ☺ | 1 | 1 | 1 | 6 | 14 |
| 7 | ☺ | 1 | 1 | 1 | 5 | 13 |
| 8 | | 1 | 0 | 1 | 4 | 12 |
| 9 | | 3 | 0 | 1 | 2 | 2 |
| 10 | | 4 | 0 | 1 | 1 | 4 |
| 11 | | 5 | 0 | 1 | 1 | 5 |
+----+------------+------------+---------+-----+------+------+
as you can see pid is repeated.
Is it possible to get like below format
pid qid
1 1,2,3,4,5
2 7,1,2
6 14
5 13
4 12
I tried like this but the output I got is
SELECT pid,GROUP_CONCAT(qid) FROM client_parent_question
------+--------------------------+
pid | GROUP_CONCAT(qid) |
------+--------------------------+
1 | 1,2,3,7,1,14,13,12,2,4,5 |
------+--------------------------+

Use GROUP BY
SELECT pid, GROUP_CONCAT(qid)
FROM client_parent_question
GROUP BY pid

You are missing group by
SELECT pid,GROUP_CONCAT(qid) FROM client_parent_question group by pid

SELECT pid,GROUP_CONCAT(qid) FROM client_parent_question
Group by PID
would do the trick. Output would be as:
pid | qid
1 | 1,2,3,4,5
2 | 7,1,2
6 | 14
5 | 13
4 | 12

Related

Update records in a select query with different values

I have an INSERT INTO query that works great to create child records when a parent record is added. I basically need to run the same thing but instead of adding new child records, I need to update the column that contains a sum value.
As an example, I have the following data. Shift_Roster_ID is the PK for the first table. RosterID and ShiftID are both foreign keys. For ShiftID=1, I want to update the ShiftCount for each unique RosterID. The ShiftCount is the sum of the Response values for any shift for which the PeriodID in the second table matches the PeriodID of ShiftID=1.
+-----------------+----------+---------+------------+----------+
| Shift_Roster_ID | RosterID | ShiftID | ShiftCount | Response |
+-----------------+----------+---------+------------+----------+
| 1 | 1 | 1 | 0 | 1 |
+-----------------+----------+---------+------------+----------+
| 2 | 2 | 1 | 0 | 3 |
+-----------------+----------+---------+------------+----------+
| 3 | 3 | 1 | 0 | 8 |
+-----------------+----------+---------+------------+----------+
| 4 | 1 | 2 | 0 | 1 |
+-----------------+----------+---------+------------+----------+
| 5 | 2 | 2 | 0 | 8 |
+-----------------+----------+---------+------------+----------+
| 6 | 3 | 2 | 0 | 7 |
+-----------------+----------+---------+------------+----------+
| 7 | 1 | 2 | 0 | 7 |
+-----------------+----------+---------+------------+----------+
| 8 | 2 | 3 | 0 | 7 |
+-----------------+----------+---------+------------+----------+
| 9 | 3 | 3 | 0 | 6 |
+-----------------+----------+---------+------------+----------+
+---------+----------+
| ShiftID | PeriodID |
+---------+----------+
| 1 | 1 |
+---------+----------+
| 2 | 1 |
+---------+----------+
| 3 | 2 |
+---------+----------+
The result should be
+-----------------+----------+---------+------------+----------+
| Shift_Roster_ID | RosterID | ShiftID | ShiftCount | Response |
+-----------------+----------+---------+------------+----------+
| 1 | 1 | 1 | **2** | 1 |
+-----------------+----------+---------+------------+----------+
| 2 | 2 | 1 | **11** | 3 |
+-----------------+----------+---------+------------+----------+
| 3 | 3 | 1 | **15** | 8 |
+-----------------+----------+---------+------------+----------+
| 4 | 1 | 2 | 0 | 1 |
+-----------------+----------+---------+------------+----------+
| 5 | 2 | 2 | 0 | 8 |
+-----------------+----------+---------+------------+----------+
| 6 | 3 | 2 | 0 | 7 |
+-----------------+----------+---------+------------+----------+
| 7 | 1 | 2 | 0 | 7 |
+-----------------+----------+---------+------------+----------+
| 8 | 2 | 3 | 0 | 7 |
+-----------------+----------+---------+------------+----------+
| 9 | 3 | 3 | 0 | 6 |
+-----------------+----------+---------+------------+----------+

How to select multiple values for one table "cell" MySQL

For all players, I need to find the player number and a list of the numbers of teams for which they have ever played.
Here is the table "MATCHES":
+---------+--------+----------+-----+------+
| MATCHNO | TEAMNO | PLAYERNO | WON | LOST |
+---------+--------+----------+-----+------+
| 1 | 1 | 6 | 3 | 1 |
| 2 | 1 | 6 | 2 | 3 |
| 3 | 1 | 6 | 3 | 0 |
| 4 | 1 | 44 | 3 | 2 |
| 5 | 1 | 83 | 0 | 3 |
| 6 | 1 | 2 | 1 | 3 |
| 7 | 1 | 57 | 3 | 0 |
| 8 | 1 | 8 | 0 | 3 |
| 9 | 2 | 27 | 3 | 2 |
| 10 | 2 | 104 | 3 | 2 |
| 11 | 2 | 112 | 2 | 3 |
| 12 | 2 | 112 | 1 | 3 |
| 13 | 2 | 8 | 0 | 3 |
+---------+--------+----------+-----+------+
The best I could come up with was:
SELECT DISTINCT playerno, teamno
FROM matches
ORDER BY playerno;
which results in:
+----------+--------+
| playerno | teamno |
+----------+--------+
| 2 | 1 |
| 6 | 1 |
| 8 | 1 |
| 8 | 2 |
| 27 | 2 |
| 44 | 1 |
| 57 | 1 |
| 83 | 1 |
| 104 | 2 |
| 112 | 2 |
+----------+--------+
Notice how player 8 has played on two teams. How can I get the table to show only one row for player 8 and a list of teamno's (1 & 2)?
You could use the group_concat aggregate function:
SELECT playerno, GROUP_CONCAT(DISTINCT teamno)
FROM matches
GROUP BY playerno
ORDER BY playerno;
You could use group_concat
SELECT playerno, group_concat( teamno)
FROM matches
GROUP BY playerno;

How to delete from a table interlinking 4 tables

Hi following are my 4 tables.
client_parent_question :-
+----+------------+------------+---------+-----+------+------+
| id | is_deleted | sort_order | version | cid | pid | qid |
+----+------------+------------+---------+-----+------+------+
| 1 | | 1 | 0 | 1 | 1 | 1 |
| 2 | | 2 | 0 | 1 | 1 | 2 |
| 3 | | 3 | 0 | 1 | 1 | 3 |
| 4 | | 4 | 0 | 1 | 1 | 4 |
| 5 | | 1 | 0 | 1 | 2 | 7 |
+----+------------+------------+---------+-----+------+------+
mysql> select * from client_parent;
+----+------------+------------+---------+-----+------+
| id | is_deleted | sort_order | version | cid | pid |
+----+------------+------------+---------+-----+------+
| 1 | | 1 | 0 | 1 | 1 |
| 2 | | 2 | 0 | 1 | 2 |
+----+------------+------------+---------+-----+------+
2 rows in set (0.00 sec)
mysql> select * from client_question;
+----+------------+---------+-----+------+------+
| id | is_deleted | version | cid | pqid | qtid |
+----+------------+---------+-----+------+------+
| 1 | | 0 | 1 | 1 | 1 |
| 2 | | 0 | 1 | 2 | 4 |
| 3 | | 0 | 1 | 2 | 4 |
| 4 | | 0 | 1 | 1 | 1 |
| 5 | | 0 | 1 | 2 | 4 |
| 6 | | 0 | 1 | 3 | 4 |
| 7 | | 0 | 1 | 3 | 4 |
| 8 | | 0 | 1 | 1 | 1 |
| 9 | | 0 | 1 | 2 | 4 |
| 10 | | 0 | 1 | 3 | 4 |
| 11 | | 0 | 1 | 4 | 4 |
| 12 | | 0 | 1 | 4 | 4 |
+----+------------+---------+-----+------+------+
mysql> select * from client_question_option;
+----+------------+---------+------+------+
| id | is_deleted | version | cqid | oid |
+----+------------+---------+------+------+
| 1 | | 0 | 2 | 1 |
| 2 | | 0 | 3 | 4 |
| 3 | | 0 | 6 | 2 |
| 4 | | 0 | 7 | 3 |
| 5 | | 0 | 11 | 1 |
| 6 | | 0 | 12 | 4 |
| 7 | | 0 | 14 | 1 |
| 8 | | 0 | 15 | 4 |
+----+------------+---------+------+------+
I know only cid and pid of client_parent table
My aim is to delete all from client_question,client_parent_question and client_question_option
In the client_question_option cqid id is the id of client_question table
Following is the sqlfiddle
I did
DELETE FROM cqo,qo,cpq client_question_option cqo ,client_question cq,client_parent_question ,client_parent cp
WHERE cqo.cqid=cq.id AND cq.pqid=pq.id AND cqo.oid=qo.id AND cq.cid=1 AND cp.pid=1
But this did not work.
You just need to move the FROM keyword after the table aliases. See multiple-table syntax
DELETE cqo, qo, cpq
FROM client_question_option cqo,
client_question cq,
client_parent_question,
client_parent cp
WHERE cqo.cqid=cq.id AND cq.pqid=pq.id AND cqo.oid=qo.id
AND cq.cid=1 AND cp.pid=1;
Your DELETE query's syntax is wrong, which must be somthing like this:-
DELETE cqo,cp,pq
FROM client_question_option cqo, client_question cq, client_parent_question pq, client_parent cp
WHERE cqo.cqid=cq.id AND cq.pqid=pq.id AND cqo.oid=cp.id AND cq.cid=1 AND cp.pid=1;
Hope this will help you.
using inner join
DELETE cqo,cq,cp,pq
FROM client_question_option cqo
INNER JOIN client_question cq
INNER JOIN client_parent_question as pq
INNER JOIN client_parent cp
WHERE cqo.cqid=cq.id AND cq.pqid=pq.id AND cqo.oid=cqo.id AND cq.cid=1 AND cp.pid=1
You have an option in MYSQL Called as ONDELETE CASCADE where in when you set this on a key
example : foreign key(cid) references client_parent(cid) ON DELETE CASCADE when you delete the key based on your condition all referencing ids will be deleted , so one simple query to delete parent row is enough for it to delete all child rows present in other table data
Advantages of using ON DELETE CASCADE
you are not require to right innerjoins and delete data manually
you dont get parent key errors
you can save up your time
Thats it NJOY!!!

select sorted tree and subtrees with materialized path

i want select tree from
id | parent_id | path | order
---------------------------------------
1 | 0 | /1/ | 1
2 | 1 | /1/2/ | 1
3 | 2 | /1/2/3/ | 1
4 | 1 | /1/4/ | 2
5 | 4 | /1/4/5/ | 2
6 | 4 | /1/4/6/ | 1
like this
| 1 | | |
| | 2 | |
| | | 3 |
| | 4 | |
| | | 6 |
| | | 5 |
in one query.
Something like
select * from tbl ORDER BY COALESCE(length(path),0), order asc
but this select sorted groups of each tree level
1
-2
-4
--3
--6
--5
thanks

join with a group by?

i have a table called rc_language_type_table with:
id language
1 english
2 Xhosa
3 afrikaans
etc
then i have a table rc_language_type_assoc_table with:
profile_id | language_type_id |
+------------+------------------+
| 3 | 1 |
| 13 | 1 |
| 15 | 1 |
| 16 | 1 |
where i have profiles and each profile is connected to a language id in a 1 to many
so then i did:
select *,count(*) from rc_language_type_assoc_table group by language_type_id;
+------------+------------------+----------+
| profile_id | language_type_id | count(*) |
+------------+------------------+----------+
| 3 | 1 | 96 |
| 3 | 2 | 19 |
| 3 | 3 | 18 |
| 64 | 4 | 51 |
| 94 | 5 | 10 |
| 37 | 6 | 26 |
| 3 | 7 | 21 |
| 3 | 8 | 4 |
| 3 | 9 | 6 |
| 88 | 10 | 4 |
| 3 | 11 | 3 |
+------------+------------------+----------+
what i want now is: instead having the language_type_id i want to display the actual language...how would i do this please???
i tried:
select *, count(*)
from rc_language_type_assoc_table, rc_language_type_table
group by language_type_id
where rc_language_type_assoc_table.language_type_id = rc_language_type_table.id;
but i get a syntax error...
please help??
thank you
GROUP BY should be "after" the WHERE statement and not before
select *, count(*)
from rc_language_type_assoc_table, rc_language_type_table
where rc_language_type_assoc_table.language_type_id = rc_language_type_table.id
group by language_type_id ;