SQL - Select all rows that have the same Email but different Name - sql

I'm trying to select all the users in a table that have the same Email but have a different Name. So far I have managed to get all the rows that have duplicate Email but I'm stuck on the next step.
SELECT * FROM users WHERE Email IN
(SELECT Email FROM users GROUP BY Email HAVING COUNT(*) > 1)
Thanks in advance

I think you just want count(distinct name) in the subquery:
SELECT *
FROM users
WHERE Email IN (SELECT Email
FROM users
GROUP BY Email
HAVING COUNT(distinct Name) > 1
) ;
I prefer having min(name) <> max(name) for the having clause. It is slightly more efficient.
However, the most efficient method is probably to use window functions:
select u.*
from (select u.*, min(name) over (partition by email) as minname,
max(name) over partition by email) as maxname
from users u
) u
where minname <> maxname;

Try this
SELECT *
FROM users U1
INNER JOIN
users U2
on U1.Email=U2.Email
AND U1.Name <> U2.Name

You can try the following:
SELECT u.*
FROM users u
LEFT JOIN (
SELECT Email
FROM users
GROUP BY Email
HAVING COUNT(*) = COUNT(DISTINCT name)
) tmp ON u.Email = tmp.Email
WHERE tmp.Email IS NOT NULL

Related

Get the first created user per organization

SELECT email, org_id, MIN(created_at) as first_user_created
FROM users
WHERE org_id IN (SELECT org_id FROM subscriptions)
GROUP BY email, org_id;
Result of the above query gives me multiple user records per org_id.
What I want: Per organization - return the email, org_id and first_user_created of user that got created the earliest.
One solution uses DISTINCT ON:
SELECT DISTINCT ON (u.org_id) u.email, u.org_id, u.created_at
FROM users u
INNER JOIN subscriptions s
ON s.org_id = u.org_id
ORDER BY u.org_id, u.created_at;
Another way to do this uses RANK():
WITH cte AS (
SELECT u.email, u.org_id, u.created_at,
RANK() OVER (PARTITION BY u.org_id ORDER BY u.created_at) rnk
FROM users u
INNER JOIN subscriptions s ON s.org_id = u.org_id
)
SELECT email, org_id, created_at
FROM cte
WHERE rnk = 1;

How to Join only first row, disregard further matches

I have 2 tables
Table Users:
UserID | Name
Table Cars:
CarID | Car Name | FK_UserID
A user can have more than 1 car.
I want to join each user with 1 car only, not more.
Having looked at other threads here,
I've tried the following:
Select users.UserID, users.name, carid
from Users
join cars
on users.UserID =
(
select top 1 UserID
from users
where UserID = CarID
)
But it still returns more than 1 match for each user.
What am I doing wrong?
You can try like below using ROW_NUMBER() function
select userid, username, carname
from
(
Select users.UserID as userid,
users.name as username,
cars.carname as carname,
ROW_NUMBER() OVER(PARTITION BY users.UserID ORDER BY users.UserID) AS r
from Users
join cars
on users.UserID = cars.FK_UserID
) XXX
where r = 1;
with x as
(select row_number() over(partition by userid order by carid) as rn,
* from cars)
select u.userid, x.carid, x.carname
from users u join x on x.userid = u.userid
where x.rn = 1;
This is one way to do it using row_number function.
Another way to do it
select u.UserID,
u.name,
(select TOP 1 carid
from cars c
where u.UserID = c.FK_UserID
order by carid) carid -- Could be ordered by anything
from Users u
-- where only required if you only want users with cars
where exists (select * from car c where u.UserID = c.FK_UserID)
Best would be to do a subquery and use a group-by in it to return only 1 user and a car for each user. Then join that to the outer user table.
Here is an example:
select *
from user_table u
join (
select userid
, max(carname)
from cars
group by userid
) x on x.userId = u.userId
or you could use the row_number() examples above if you want a specific order (either this example or theirs will do the trick)

max(count(*)) Error: single-group group function

Assume I have two tables:
users
sells
I need to alter this query: Show top three users who bought copies of softwareMy SQL is this:
select u.name, u.age, u.sex, u.email, s.selluid, max(count(u.uid)) FROM users u, sells s where u.usrid = s.selluid
Any idea about how to solve this problem? Thanks
Try this
select u.usrid, u.name, count(s.sellid)
from users u left join sells s on u.usrid=s.selluid
group by u.usrid, u.name order by count(s.sellid) desc;
You can solve this using an aggregation subquery with row_number():
select u.*, s.numsales
from users u join
(select s.selluid, count(*) as numsales,
row_number() over (order by count(*) desc) as seqnum
from sells s
group by s.selluid
) s
on u.userid = s.selluid
where seqnum <= 3;
One advantage to this approach is that you can readily get all the columns from users using just u.*.
SELECT x.*
FROM (
SELECT u.name
, u.age
, u.sex
, u.email
, s.selluid
, COUNT(*) as t
FROM users u JOIN sells s ON u.usrid = s.selluid
GROUP BY u.name
ORDER BY COUNT(*) DESC
) x
WHERE ROWNUM <= 3

postgresql database

i wanna to make a query that select users that have same username and same hour of creation date by using postgresql database
Something like this should do the trick. This will return any user/hour pair along with the count (untested):
select users.username, datepart('hour', users.created_at), count(*) from users
inner join users u2
on users.username = u2.username
and datepart('hour', users.created_at) = datepart('hour', u2.created_at)
group by users.username, datepart('hour', users.created_at) having count(*) > 1
select u.*
from users u
join (
select username, date_trunc('hour', creation_timestamp)
from users
group by 1, 2
having count(*) > 1
) as x on u.username = x.username
order by u.username;
Should work nicely.

How to select all users who made more than 10 submissions

I have a submission table that is very simple: userId, submissionGuid
I want to select the username (simple inner join to get it) of all the users who have more than 10 submissions in the table.
I would do this with embedded queries and a group by to count submissions... but is there a better way of doing it (without embedded queries)?
Thanks!
This is the simplest way, I believe:
select userId
from submission
group by userId
having count(submissionGuid) > 10
select userId, count(*)
from submissions
having count(*) > 10
group by userId
SELECT
username
FROM
usertable
JOIN submissions
ON usertable.userid = submissions.userid
GROUP BY
usertable.username
HAVING
Count(*) > 1
*Assuming that your "Users" table is call usertable and that it has a column called "UserName"
I think the correct query is this (SQL Server):
SELECT s.userId, u.userName
FROM submission s INNER JOIN users u on u.userId = s.userId
GROUP BY s.userId, u.username
HAVING COUNT(submissionGuid) > 10
If you don't have the HAVING clause:
SELECT u.userId, u.userName
FROM users u INNER JOIN (
SELECT userId, COUNT(submissionGuid) AS cnt
FROM submission
GROUP BY userId ) sc ON sc.userId = u.userId
WHERE sc.cnt > 10
select userid, count(submissionGUID) as submitCount
from Submissions
group by userid, submitCount
having submitCount > 10