put some column values in a new column using sql - mysql

I have table like this
user_id workplace
1 Microsoft
1 Google
2 eBay
3 Panadora
3 Netflix
What I want is to have a table like this:
user_id places_worked
1 Microsoft,Google
2 eBay
3 Panadora,Netflix
Is there anyway in SQL that can do this?

As mentioned by #jarlh you could do this using group_concat
SELECT user_id,GROUP_CONCAT(workplace)
FROM yourtable
GROUP BY user_id;

you can use group by with group concat operation
SELECT user_id,GROUP_CONCAT(workplace)
FROM yourtable
GROUP BY user_id;
check following example
select * from payments;
+----+------------+---------+-------+
| id | date | user_id | value |
+----+------------+---------+-------+
| 1 | 2016-06-22 | 1 | 10 |
| 2 | 2016-06-22 | 3 | 15 |
| 3 | 2016-06-22 | 4 | 20 |
| 4 | 2016-06-23 | 2 | 100 |
| 5 | 2016-06-23 | 1 | 150 |
+----+------------+---------+-------+
5 rows in set (0.00 sec)
select c.user_id,group_concat(p.value) from calls c inner join payments p on p.user_id=c.user_id group by c.user_id;
+---------+-----------------------+
| user_id | group_concat(p.value) |
+---------+-----------------------+
| 1 | 10,150,10,150,10,150 |
| 2 | 100 |
+---------+-----------------------+
2 rows in set (0.00 sec)

Related

How to get 2nd highest salary of each employee in employee table which contains more than one entry in employee table

i am not asking about 2nd highest salary in employee table , i am asking about 2nd highest salary of each employee.
click here to see employee table
inner query will return employees with their highest salary and then from out query those highest salaries will be filtered out
so you will get the second highest salary
SELECT MAX(T.salery),T.NAME FROM TABLE T
INNER JOIN (SELECT MAX(salery),NAME FROM TABLE GROUP BY NAME) TT
ON TT.NAME=T.NAME AND TT.SALERY!= T.SALERY
GROUP BY T.NAME;
example
mysql> SELECT * FROM payments;
+----+------------+---------+-------+
| id | date | user_id | value |
+----+------------+---------+-------+
| 1 | 2016-06-22 | 1 | 10 |
| 2 | 2016-06-22 | 3 | 15 |
| 3 | 2016-06-22 | 4 | 20 |
| 4 | 2016-06-23 | 2 | 100 |
| 5 | 2016-06-23 | 1 | 150 |
| 6 | 2016-06-23 | 2 | 340 |
+----+------------+---------+-------+
6 rows in set (0.00 sec)
mysql> select max(value),user_id from payments group by user_id;
+------------+---------+
| max(value) | user_id |
+------------+---------+
| 150 | 1 |
| 340 | 2 |
| 15 | 3 |
| 20 | 4 |
+------------+---------+
4 rows in set (0.00 sec)
mysql> select max(T.value),TT.user_id from payments T inner join (select max(value) as val,user_id from payments group by user_id) TT on T.value!=TT.val and T.user_id=TT.user_id group by T.user_id;;
+--------------+---------+
| max(T.value) | user_id |
+--------------+---------+
| 10 | 1 |
| 100 | 2 |
+--------------+---------+
2 rows in set (0.00 sec)
I think a very quick solution could be like this:
SELECT MAX(column) FROM table WHERE column < (SELECT MAX(column) FROM table)
Hope it helps-

Finding average of the column generated from sql query having group by function

I want to find the average of the following data via mysql query (assume these are 719 rows).
| 1 |
| 3 |
| 1 |
| 2 |
| 2 |
| 1 |
| 1 |
| 2 |
| 1 |
| 1 |
| 2 |
| 1 |
| 2 |
| 1 |
| 2 |
| 1 |
| 1 |
+----------+
719 rows in set (2.43 sec)
SELECT COUNT(*) FROM osdial_agent_log WHERE DATE(event_time)='2015-11-01' GROUP BY lead_id;
I ran this query to get that data
Can someone help me to find the average for the above data.
Use
SELECT AVG(total)
FROM (SELECT COUNT(*) AS total
FROM osdial_agent_log
WHERE DATE(event_time)='2015-11-01'
GROUP BY lead_id) t

mysql: order -> limit -> sum... possible?

i am loosing it over the following problem:
i have a table with participants and points. each participant can have up to 11 point entries of which i only want the sum of the top 6.
in this example lets say we want the top 2 of 3
+----+---------------+--------+
| id | participantid | points |
+----+---------------+--------+
| 1 | 1 | 11 |
+----+---------------+--------+
| 2 | 3 | 1 |
+----+---------------+--------+
| 3 | 3 | 4 |
+----+---------------+--------+
| 4 | 2 | 3 |
+----+---------------+--------+
| 5 | 1 | 5 |
+----+---------------+--------+
| 6 | 2 | 10 |
+----+---------------+--------+
| 7 | 2 | 9 |
+----+---------------+--------+
| 8 | 1 | 3 |
+----+---------------+--------+
| 9 | 3 | 4 |
+----+---------------+--------+
as a result i want something like
+---------------+--------+
| participantid | points |
+---------------+--------+
| 2 | 19 |
+---------------+--------+
| 1 | 16 |
+---------------+--------+
| 3 | 8 |
+---------------+--------+
(it should be ordered DESC by the resulting points)
is this at all possible with mysql? in one query?
oh and the resulting participant ids should be resolved into the real names from another 'partcipant' table where
+----+------+
| id | name |
+----+------+
| 1 | what |
+----+------+
| 2 | ev |
+----+------+
| 3 | er |
+----+------+
but that should be doable with a join at some point... i know...
Using one of the answers from ROW_NUMBER() in MySQL for row counts, and then modifying to get the top.
SELECT ParticipantId, SUM(Points)
FROM
(
SELECT a.participantid, a.points, a.id, count(*) as row_number
FROM scores a
JOIN scores b ON a.participantid = b.participantid AND cast(concat(a.points,'.', a.id) as decimal) <= cast(concat(b.points,'.', b.id) as decimal)
GROUP BY a.participantid, a.points, a.id
) C
WHERE row_number IN (1,2)
GROUP BY ParticipantId
Had an issue with ties until I arbitrarily broke them with the id

SQL, difficult fetching data query

Suppose I have such a table:
+-----+---------+-------+
| ID | TIME | DAY |
+-----+---------+-------+
| 1 | 1 | 1 |
| 2 | 2 | 1 |
| 3 | 3 | 1 |
| 1 | 1 | 2 |
| 2 | 2 | 2 |
| 3 | 3 | 2 |
| 1 | 1 | 3 |
| 2 | 2 | 3 |
| 3 | 3 | 3 |
| 1 | 1 | 4 |
| 2 | 2 | 4 |
| 3 | 3 | 4 |
| 1 | 1 | 5 |
| 2 | 2 | 5 |
| 3 | 3 | 5 |
+-----+---------+-------+
I want to fetch a table which represents 2 IDs which got the largest sum of TIME within the last 3 days (means from 3 to 5 in a DAY column)
So the correct result would be:
+-----+---------+
| ID | SUM |
+-----+---------+
| 3 | 9 |
| 2 | 6 |
+-----+---------+
The original table is much larger and more complex. So i need a generic approach.
Thanks in advance.
And so I just learned that MySQL used LIMIT instead of TOP...
fiddle
CREATE TABLE tbl (ID INT,tm INT,dy INT);
INSERT INTO tbl (id, tm, dy) VALUES
(1,1,1)
,(2,2,1)
,(3,3,1)
,(1,1,2)
,(1,1,1)
SELECT ID
,SUM(SumTimeForDay) SumTimeFromLastThreeDays
FROM (SELECT ID
,SUM(tm) SumTimeForDay
FROM tbl
GROUP BY ID, dy
HAVING dy > MAX(dy) -3) a
GROUP BY id
ORDER BY SUM(SumTimeForDay) DESC
LIMIT 2
select t1.`id`, sum(t1.`time`) as `sum`
from `table` t1
inner join ( select distinct `day` from `table` order by `day` desc limit 3 ) t2
on t2.`da`y = t1.`day`
group by t1.`id`
order by sum(t1.`time`) desc
limit 2

selecting all duplicates

How can I update this to select all duplicates?
SELECT address FROM list
GROUP BY address HAVING count(id) > 1
Currently, I think it just returs the addresses which are duplciated. I want all duplicates.
Select * from list
where address in (
select address from list group by address
having count(*) > 1);
Look at this sample query I ran:
mysql> select * from flights;
+--------+-------------+
| source | destination |
+--------+-------------+
| 1 | 2 |
| 3 | 4 |
| 5 | 6 |
| 6 | 1 |
| 2 | 4 |
| 1 | 3 |
| 5 | 2 |
| 6 | 3 |
| 6 | 5 |
| 6 | 4 |
+--------+-------------+
10 rows in set (0.00 sec)
mysql> select * from flights where source in
(select source from flights group by source having count(*) > 1);
+--------+-------------+
| source | destination |
+--------+-------------+
| 1 | 2 |
| 5 | 6 |
| 6 | 1 |
| 1 | 3 |
| 5 | 2 |
| 6 | 3 |
| 6 | 5 |
| 6 | 4 |
+--------+-------------+
8 rows in set (0.00 sec)
If I'm correct, you're looking for the actual rows that contain duplicates -- so that if you have three rows with the same address, you return all three rows.
Here's how to do it:
SELECT * FROM list
WHERE address in (
SELECT address FROM list GROUP BY address HAVING count(id) > 1
);
This should generally work unless your address is a 'text' field or if your address table has more than a few thousand duplicates.
Are you looking for this?
SELECT * FROM list
WHERE id IN (
SELECT id FROM list
GROUP BY address HAVING count(id) > 1
);