Reputation: 43
I'm running into a problem where I'm trying to return rows that has only 1 value match in a column. For example:
CREATE TABLE TEST
(
ID INT PRIMARY KEY,
FIRSTNAME VARCHAR(30) NOT NULL,
LASTNAME VARCHAR(30) NOT NULL,
EMAIL VARCHAR(50),
PHONENUMBER VARCHAR(50)
STAMP DATETIME
)
INSERT INTO TEST VALUES (1, 'Tom', 'Lew', '[email protected]', '11111111111', '2019-08-23 15:12:06.807')
INSERT INTO TEST VALUES (2, 'Tom', 'Lew', '[email protected]', '22222222222', '2019-08-27 15:12:06.807')
INSERT INTO TEST VALUES (3, 'Jack', 'Stan', '[email protected]', '3333333333', '2019-08-03 15:12:06.807')
INSERT INTO TEST VALUES (4, 'John', 'Doe', '[email protected]', '44444444444', '2019-08-13 15:12:06.807')
INSERT INTO TEST VALUES (5, 'Peter', 'Griffin', '[email protected]', '55555555555', '2019-07-23 15:12:06.807')
INSERT INTO TEST VALUES (6, 'Homer', 'Simpson', '[email protected]', '66666666666', 2019-08-23 15:12:06.807')
SELECT FirstName, LastName, Email, PhoneNumber
FROM TEST GROUP BY FirstName, LastName, Email, PhoneNumber
HAVING COUNT (FirstName) <= 1
So the result is supposed return everything except for 'Tom' because 'Tom' has more than 1 value matches in the First Name column. However, it's returning everything.
If I do a SELECT FirstName, LastName, Email and GROUP BY FirstName, LastName, Email, it comes back correctly.
Upvotes: 1
Views: 3044
Reputation: 61
I will exclude the duplicate record using ROW_NUMBER():
SELECT * FROM(
SELECT firstname, lastname, email, phonenumber,
ROW_NUMBER() OVER(PARTITION BY firstname ORDER BY firstname) AS rn
FROM test
)
WHERE rn=1;
Hope this helps.
Upvotes: 0
Reputation: 164054
Since you check for unique FirstName
s you should only GROUP BY FirstName
and aggregate on the other columns with MAX()
or MIN()
(it does not make any difference because the condition in the HAVING
clause makes sure that only 1 value of these columns exists):
SELECT FirstName,
MAX(LastName) LastName, MAX(Email) Email, MAX(PhoneNumber) PhoneNumber
FROM TEST
GROUP BY FirstName
HAVING COUNT(*) = 1
See the demo.
Results:
| FirstName | LastName | Email | PhoneNumber |
| --------- | -------- | -------------------- | ----------- |
| Homer | Simpson | [email protected] | 66666666666 |
| Jack | Stan | [email protected] | 3333333333 |
| John | Doe | [email protected] | 44444444444 |
| Peter | Griffin | [email protected] | 55555555555 |
Upvotes: 0
Reputation: 390
The problem with your select query is two toms' don't have the same phonenumber. If you are going to include the phonenumber in the GROUP BY
clause it will give you 2 unique rows for both the toms. You need to decide your unique composite columns for GROUP BY
.
If you are only concerned about FirstName your query will be like this.
SELECT FirstName, LastName, Email, PhoneNumber
FROM TEST GROUP BY FirstName
HAVING COUNT (FirstName) <= 1
If you are taking LastName and Email into GROUP BY
, then:
SELECT FirstName, LastName, Email, PhoneNumber
FROM TEST GROUP BY FirstName, LastName, Email
HAVING COUNT (FirstName) <= 1
Upvotes: 0
Reputation: 1269503
You can use not exists
. If you only care about the first name:
select t.*
from test t
where not exists (select 1
from t t2
where t2.firstname = t.firstname and
t2.id <> t.id
);
Upvotes: 6