mysql GROUP BY query showing partial matches in email field - mysql

I have the following query for finding duplicate email addresses in mysql db .
It's returning partial match duplicate values , how can get only exact matches ?
SELECT id, email, date FROM mytable GROUP BY email HAVING COUNT(email) > 1
For example its giving following results:
1234567890#foo.net
1234567890#bar.net
or
123#foo.com
456#foo.com
or
100abc#gmail.com
100xyz#foo.com
100xhsy#bar.com

#Abey I do this by joining the table into itself on the field I want to show is identical but where a truly unique value (like id) is different between the two records.
Here is how you would do that:
SELECT `mt1`.`id`,
`mt1`.`email`,
`mt1`.`date`
FROM `mytable` AS `mt1`
JOIN `mytable` AS `mt2` ON `mt2`.`email` = `mt1`.`email`
AND `mt2`.`id` <> `mt1`.`id`
GROUP BY `mt1`.`id`
If you want to have a distinct list of the duplicate emails and don't care to see each individual record, just trim out the other fields you are returning like this:
SELECT `mt1`.`email`
FROM `mytable` AS `mt1`
JOIN `mytable` AS `mt2` ON `mt2`.`email` = `mt1`.`email`
AND `mt2`.`id` <> `mt1`.`id`
GROUP BY `mt1`.`email`
Here is an example mocked up in sqlfiddle.
Hope this helps!

Related

How could I get a list of unique records from below duplicated records by ignoring first two characters?

Here is the rule:
When comparing userId, only search userId starting with 'AB' and its matching duplicates (except 'AB'). Then get a list of "unique userId" by only returning above duplicated userId that is having 'AB' at the beginning.
For returned duplicated string starting with 'AB', we need to make sure there is "duplicate"; otherwise, we should not return 0 record
I know it sounds confusing, please see example below:
Table UserName with ten records, and its userId fields (10 records) are:
ABC1234
C1234
C12345
BC12345
BBC1234
ABF1235
F1235
ABY1236
BCD3456
D3456
Desired Result after running query:
ABC1234
ABF1235
Please note: Although ABY1236 starts with 'AB', this record should not be returned in output, since it doesn't have a "duplicate" match like Y1236 (ignoring first two character, 'AB').
I have a sample query below, but it only returned duplicated record NOT starting with 'AB', also it will return ABY1236.
SELECT distinct substr(userId , -(length(userID)-2))
from UserName where userId like 'AB%';
Thanks for the help!
You can use EXISTS to check if there is a userId that is equal to the right part of "AB.." starting from the 3d char:
select u.userId from UserName u
where
u.userId like 'AB_%'
and
exists (
select 1 from UserName where userId = substr(u.userId, 3)
)
You could try using a selct join for check only the matching result
SELECT substr(a.userId , -(length(a.userID)-2))
from UserName a
INNER JOIN UserName b ON a.substr(a.userId , -(length(a.userID)-2)) = b.UserId
AND userId like 'AB%'

SQL: have duplicates for each ID, I would like to keep the ID with site that is not blank

ID Site
a www.google.com
a
b www.qq.com
b
c www.hodes.com
.
.
.
I have a table like the one above, I'd like to extract the the site value is not blank, such as:
ID Site
a www.google.com
b www.qq.com
c www.hodes.com
You just have to check if the content of the column site is null or not. In order to select the rows with content:
SELECT * FROM TABLE_NAME WHERE SITE IS NOT NULL
Read more here.
select * from table where Site <> '' or Site is not null
will work if the blank ones are ALWAYS duplicates.
otherwise
select max(id), max(site) from table group by id
Should be okay
select
ID,
max(if(trim(site) = '', null, site)) as site
from tbl
group by ID
;
You could substitute GROUP_CONCAT for max if more than one site per ID.
I'm gonna go on a limb and assume that you want to remove the empty rows from your database. If that's not the case, just move the where clause to a Select statement.
Delete from TableName where ISNULL(Site, '')=''
If you must return one and only one record per id, then your code must
cope with potential multiple records per id -- and you need the max() and group by .
I would suggest:
Select id, max(site)
from table_name
where nvl(site,0) <> 0
group by id
Else if you know that you'd never encounter multiple records with the same id:
Select id, site
from table_name
where nvl(site,0) <> 0

Select data from another table with where clause

What's wrong with this query, im selecting data from 3 different tables here. First title of exam from "class_exams" table , second selecting sum of total marks from "results" table. Query works fine without where clause.
SELECT id, exam_date , (
SELECT title
FROM class_exams
WHERE result_heads.exam_id = class_exams.id
) AS exam_title, (
SELECT sum( marks )
FROM results
WHERE result_heads.id = results.head_id
) AS obt_marks
FROM `result_heads` WHERE exam_title = 'test';
Error comes
Unknown column 'exam_title' in 'where clause'
Consider using Join
If I understand the table schema , it should be like this :
SELECT result_heads.id, result_heads.exam_date , sum( results.marks )AS obt_marks
FROM results JOIN result_heads
ON results.exam_id = result_heads.id
GROUP BY result_heads.id, result_heads.exam_date
I think you need to add the name of table in where clouse
WHERE `tbl_name`.`exam_title = 'test';
I know this is an old post, but I like to fill the answers where old posts end to prevent dead end posting. It looks like the table name is not being called out in the From clause
See this link http://www.techonthenet.com/mysql/where.php and look at the example - Joining Tables.

mySQL - INSERT query that matches the same records as this SELECT query?

I've got a select query I'm using to pick out contacts in my DB that haven't been spoken to in a while. I'd like to run an INSERT query to enter in a duplicate note for all the records that are returned with this select query... problem is I'm not exactly sure how to do it.
The SELECT query itself is likely a bit of a convoluted mess. I basically want to have the most recent note from each partner selected, then select ONLY partners that haven't got a note from a certain date and back... the SELECT query goes:
SELECT * FROM
(
SELECT * FROM
(
SELECT
partners.partners_id,
partners.CompanyName,
notes.Note,
notes.DateCreated
FROM
notes
JOIN
partners ON notes.partners_id = partners.partners_id
ORDER BY notes.DateCreated DESC
) AS Part1
GROUP BY partners_id
ORDER BY DateCreated ASC
) AS Part2
WHERE
DateCreated <= '2013-01-15'
How would a run an INSERT query that would only go into the same records as this SELECT?
The insert would enter records such as:
INSERT INTO notes
(
notes_id,
partners_id,
Note,
CreatedBy,
DateCreated
)
SELECT
UUID(),
partners.partners_id,
'Duplicated message!',
'User',
'2013-02-14'
FROM
partners
If you want to do this all in SQL, you could use an UPDATE statement.
UPDATE tablename SET note='duplicate' where id in ( your statement here);
Note that in order for this to work 'id' needs to be a column from 'tablename'. Then, your statement has to return a single column, not *. The column returned needs to be the id that will let your update statement know which rows to update in 'tablename'.

Combine Update and Select Query

I got two MySQL working fine and i'm trying to find a way to combine them into one single query.
First, it selects ID of an employee.
SELECT 'ID' FROM `employee` ORDER BY ID DESC LIMIT 1;
Let's say it returns ID 100;
Then update data of employees whose ID is 100
UPDATE 'LOG' SET `TIME_EXIT`='2013/02/22' WHERE `ID`='100';
Can i do it all in a single query?
Just add them together:
UPDATE LOG SET TIME_EXIT = '2013/02/22'
WHERE ID = (
SELECT ID
FROM employee
ORDER BY ID DESC
LIMIT
);
But based on that code currently it'll only ever update the last employee, you will need to select the correct employee by using some other identifier to ensure you have the correct one.
UPDATE LOG SET TIME_EXIT = '2013/02/22'
WHERE ID = (
SELECT ID
FROM employee
WHERE NAME = 'JOHN SMITH'
ORDER BY ID DESC
LIMIT 1
);
It's now a few months old, but maybe helps you or others finding this via google…
If you want to UPDATE a field in the same selected table use this:
UPDATE LOG SET
TIME_EXIT = '2013/02/22'
WHERE ID = (
SELECT ID
FROM (
SELECT ID
FROM LOG
WHERE whatEverYouWantToCheck = whateverYouNeed
) AS innerResult
)
So, you SELECT id from a subselect. If you try to subselect it directly, mySQL quites with your error message You can't specify target table 'log' for update in FROM clause, but this way you hide your subsubquery in a subquery and that seems to be fine. Don't forget the AS innerResult to avoid getting the error message #1248 - Every derived table must have its own alias. Also match the subsubquery field name to the subquery field name in case you do something like SELECT COUNT(*) or SELECT CONCAT('#', ID)