I have a MySQL table which has three columns:
Userid | Email | Points
---------------------------------------------------------
1 | jdoe#company.com | 20
2 | jdoe%40company.com | 25
3 | rwhite#company.com | 14
4 | rwhite%40company.com| 10
What I want to do is to delete duplicate email and merge points. I want my table to look like this:
Userid | Email | Points
---------------------------------------------------------
1 | jdoe#company.com | 45
3 | rwhite#company.com | 24
How would my query look like to return my desire table?
Anyone knows how to do this ?
Thanks in advance!
Are you looking for something like this?
SELECT MIN(userid) userid, email, SUM(points) points
FROM
(
SELECT userid, REPLACE(email, '%40', '#') email, points
FROM table1
) q
GROUP BY email
Output:
| USERID | EMAIL | POINTS |
|--------|--------------------|--------|
| 1 | jdoe#company.com | 45 |
| 3 | rwhite#company.com | 24 |
Here is SQLFiddle demo
Now if you want to deduplicate your table in-place you can do
-- Fix emails
UPDATE table1
SET email = REPLACE(email, '%40', '#')
WHERE email LIKE '%\%40%';
-- Merge points for duplicate records
UPDATE table1 t JOIN
(
SELECT email, SUM(points) points
FROM table1
GROUP BY email
HAVING COUNT(*) > 1
) q ON t.email = q.email
SET t.points = q.points;
-- Delete all duplicate records except ones with lowest `userid`
DELETE t
FROM table1 t JOIN
(
SELECT MIN(userid) userid, email
FROM table1
GROUP BY email
HAVING COUNT(*) > 1
) q ON t.email = q.email
WHERE t.userid <> q.userid;
Here is SQLFiddle demo
Use this query assuming you want to match email as is without any modification
SELECT MIN(user_id), SUM(points)as points, email FROM table_name GROUP BY email
Related
I want to remove all duplicates where combination of first name and last name is same
table users
mysql> select * from users;
+----+------------+-----------+
| id | LastName | FirstName |
+----+------------+-----------+
| 1 | Kowalski | Jan |
| 2 | Malinowski | Marian |
| 3 | Malinowski | Marian |
| 4 | Kowalski | Jan |
| 5 | Malinowski | Marian |
| 6 | Malinowski | Marian |
+----+------------+-----------+
I've created script
set #x = 1;
set #previous_name = '';
DELETE FROM users where id IN (SELECT id from (
select id, #previous_name,IF (CONCAT(FirstName, LastName) = #previous_name, #x:= #x + 1, IF(#previous_name:=CONCAT(FirstName, LastName), #x, IF(#x:=1, #x, #x))) as occurance
from users order by CONCAT(FirstName, LastName)
) AS occurance_table where occurance_table.occurance > 1);
but sql returns error
ERROR 1292 (22007): Truncated incorrect DOUBLE value: 'JanKowalski'
I found a few similar questions, but solution were remove and word form syntax.
I want to prepare db for adding unique constrain for 2 columns, so I want to clear table from duplications.
What is best way to reach it?
I tried with the query mentioned in Answer section.
I believe that does not work. Instead I have modified the query to work
DELETE FROM users
WHERE id NOT IN
(
SELECT MIN(a.id)
FROM (SELECT * FROM users) a
GROUP BY a.LastName, a.FirstName
)
Please do correct me if I am wrong. #juergen
There is no need for a script. A single query is enough:
delete u1
from users u1
left join
(
select min(id) as min_id
from users
group by LastName, FirstName
) u2 on u1.id = u2.min_id
where u2.min_id is null
The subselect gets the lowest user id for each unique set of name. Joining to that you can delete everything else.
I have two tables in MySQL:
___Table1
| id | name |
|----|------|
| 98 | Fred |
___Table2
| link | amount |
|------|--------|
| 98 | 100.00 |
| 98 | 50.00 |
How can I SELECT all the items from ___Table1 and SUM datas from the ___Table2.
The desired output should be:
Fred = 150.00
This is what I have tried so far:
SELECT
SELECT SUM(amount) AS amount FROM ___Table2 WHERE ___Table2.link = ___Table1.id,
(SELECT * FROM ___Estimates ORDER BY EST_Id DESC)
Thanks.
SELECT
t1.id AS id,
t1.name as name,
IFNULL ( SUM( t2.amount ), 0 ) AS account
FROM
___Table2 t2
RIGHT JOIN ___Table1 t1 ON t2.link = t1.id
GROUP BY
t2.link
You could group by name instead but you didn't say if it was unique. If you just need a single user then add a where clause to select that user:
select name, sum(amount) as 'sum'
from ___Table1
join ___Table2 on ___Table1.id = ___Table2.link
group by ___Table1.id
Those table names are awful (you can't tell how many underscores by just looking at it), also it's a good idea to use the same name for the primary and foreign key (_id is the often used standard).
So i have the following table:
userid | name | referralcode
When users register on the website they put the referralcode of someone else (the referral code is the same number as the userid of someone else)
so im looking for a sql query that will output something like this
20 (this means 20 users have this userid on their referral code) , Gerardo Bastidas, Valencia
10 , Juan Bastidas, Valencia
I want to get all info on user. its all located in the same table.
Try this query:
SELECT yt1.*, COALESCE(yt2.referral_count, 0)
FROM yourtable yt1 LEFT JOIN
(
SELECT t1.userid, COUNT(*) AS referral_count
FROM yourtable t1 INNER JOIN yourtable t2
ON t1.userid = t2.referralcode
GROUP BY t1.userid
) yt2
ON yt1.userid = yt2.userid;
This query does a self-join and will list every user along with the number of referral codes where his userid appears.
This code will do the work in one query. Replace your table name with 'tbName'
Tested and working
SELECT countval, userid, email, address
FROM tbName t1 LEFT JOIN
(
SELECT COUNT(t2.userid) ASs countval, tt.userid AS xx
FROM tbName t2
GROUP BY t2.referralcode
) t3
ON t3.xx = t1.userid
Output:
+-------+-----+------+
| count | uid | name |
+-------+-----+------+
| 3 | 1 | abc |
| 2 | 2 | xyz |
| 5 | 3 | kmn |
+-------+-----+------+
I have a table like this:
---------------------
| id | user | group |
---------------------
| 0 | 103 | 27 |
| 1 | 107 | 31 |
| 2 | 103 | 32 |
| 3 | 112 | 31 |
| 4 | 135 | 64 |
| 5 | 135 | 66 |
---------------------
This is table of groups and users and as you can see there can be records with same user and different groups. How can I select, for example, the records with same user and two groups - 27 and 32? It would be the same user.
So, how can I do this?
EDIT: To show expected result I wrote a sample:
SELECT user FROM table ... (maybe WHERE group = 27 AND group = 32)
-- gives user id 103
EDIT 2: I've found it!
Here is query that perfectly working for me:
SELECT * FROM table
WHERE `user` in
(
SELECT `user` FROM table
WHERE `group` = <needed_group_1>
)
AND `group` = <needed_group_2>
Thank's to all for help, I've found all your answers useful!
To get all data that has more than 1 group do
select * from your_table
where `user` in
(
select `user`
from your_table
group by `user`
having count(distinct `group`) >= 2
)
To get the data that has 2 specific groups do
select * from your_table
where `user` in
(
select `user`
from your_table
group by `user`
having sum(`group` in (27,32)) >= 2
)
SELECT user
FROM theTable
GROUP BY user
HAVING COUNT(group) = 2
This might also help you:
SELECT
user,
COUNT(*) as cnt,
GROUP_CONCAT(group)
FROM theTable
GROUP BY user
And if you want to grab all records that match your condition:
SELECT theTable.*
FROM theTable
JOIN (
SELECT user
FROM theTable
GROUP BY user
HAVING COUNT(group) = 2
) AS UsersWithTwoGroups USING(user)
you almost got it
try this
SELECT user FROM table1 WHERE id in ( select `group` = 27 AND `group` = 32
from table1)
group by user
NOTE. : group is reserved mysql keyword so escape it by backticks
this will give :
USER
103
DEMO HERE
I have got the following table where if more than 1 row contain the same 'user_badge_name' and the 'user_email', the are considered duplicates.
user_id | user_name | user_badge_name | user_email
--------------------------------------------------
234 | Kylie | ky001 | kylie#test.com
235 | Francois | FR007 | france#test.com
236 | Maria | MA300 | Marie#test.com
237 | Francine | FR007 | france#test.com
I need to display the user_ids and username of those rows where 'user_badge_name' and 'user_email' are replicated.
I tried the following sql but it is not returning all user_ids, only the first id
SELECT user_id, username , COUNT(user_badge_name) AS user_badge_name_Count FROM user GROUP BY user_badge_name HAVING user_badge_name_Count > 1
Any suggestion is most appreciated
select a.user_id, a.user_name
from user as a
inner join
(SELECT user_badge_name, user_email
FROM user
GROUP BY user_badge_name, user_email
HAVING count(*)>1
) as dups
on a.user_badge_name=dups.user_badge_name and a.user_email=dups.user_email
order by a.user_badge_name, a.user_email
If you want to see all of the user ids in the same row, then you can used a GROUP_CONCAT:
SELECT GROUP_CONCAT(user_id) AS user_ids, GROUP_CONCAT(username) AS usernames, COUNT(user_badge_name) AS user_badge_name_Count FROM user GROUP BY user_badge_name HAVING user_badge_name_Count > 1
That will give you something like this:
user_ids | usernames | user_badge_name_Count
-----------------------------------------------
235,237 | Francois,Francine | 2