Reputation: 33
Lets say I have two tables, Members and Orders with a 1:N relation:
Members | Orders
UserID Name | OrderID UserID Name
111 Peter | 777 111 Peter
222 Bart | 888 333 Joe
333 Joe | 999 111 Peter
444 Andrew | 101 444 Andrew
| 102 111 Peter
| 103 333 Joe
I am trying to get the Members ID from the Members table, in case that Member has more than 1 order in the Orders table.
So the result should be...
Members
UserID Name
111 Peter
333 Joe
...because Peter and Joe both have at least 2 orders in the Orders table.
I have tried to get a result with:
SELECT
s.UserID,
FROM Members s
INNER JOIN Orders o
ON s.UserID = o.UserID
WHERE
s.UserID IN
(
SELECT UserID
FROM Orders
GROUP BY UserID
HAVING COUNT(*) > 5
)
But that gives me Peter back 3 times, and Joe 2 times; so I get duplicates instead of each UserID once. How can I get the result without duplicates?
Upvotes: 3
Views: 6764
Reputation: 216
Here the answer, try to avoid DISTINCT
SELECT
UserID
,counts.count
FROM
Members mem
JOIN (SELECT UserID,COUNT(*) as 'count' FROM Orders WHERE COUNT(*) > 1 GROUP BY UserID) counts
ON mem.UserID = counts.UserID
Upvotes: 0
Reputation: 3943
Is it this what your looking for?
SELECT
s.UserID,
s.Name
FROM
Members s
INNER JOIN
Orders o ON s.UserID = o.UserID
GROUP BY
s.UserID
HAVING
COUNT(*) > 5
Upvotes: 3
Reputation: 2465
You just need a subquery having count(OrderID) > 1
as below.
SELECT *
FROM members
WHERE UserID IN (
SELECT UserId
FROM orders
GROUP BY userid
HAVING count(OrderID) > 1
);
Result:
UserID Name
--------------
111 Peter
333 Joe
Upvotes: 1
Reputation: 2885
I'm assuming (and hoping) that you're not storing the user's name twice, since that leads to data quality issues when the user changes their name.
Assuming the tables are structured like below:
CREATE TABLE
Members
(
UserID INT,
Name VARCHAR(15)
);
INSERT INTO
Members
VALUES
(111, 'Peter'),
(222, 'Bart'),
(333, 'Joe'),
(444, 'Andrew');
CREATE TABLE
Orders
(
OrderID INT,
UserID INT
);
INSERT INTO
Orders
VALUES
(777, 111),
(888, 333),
(999, 111),
(101, 444),
(102, 111),
(103, 333);
You can use a GROUP BY
and HAVING
clause which would give you the UserID
of all users with more than 1 (or whichever number you choose) orders. Then, you join that to the Members
table to get the name.
SELECT
Orders.UserID,
Members.Name
FROM
Orders
INNER JOIN
Members
ON Orders.UserID = Members.UserID
GROUP BY
UserID,
Members.Name
HAVING
COUNT(OrderID) > 1;
SQLFiddle: http://sqlfiddle.com/#!9/1dadc4/2
However, if you already have the names stored (and that's not changing), then you could skip the JOIN
like below:
SELECT
UserID,
Name
FROM
Orders
GROUP BY
UserID,
Name
HAVING
COUNT(OrderID) > 1
Upvotes: 7
Reputation: 496
To remove duplicates, use DISTINCT.
SELECT
DISTINCT
s.UserID
FROM Members s
INNER JOIN Orders o
ON s.UserID = o.UserID
WHERE
s.UserID IN
(
SELECT UserID
FROM Orders
GROUP BY UserID
HAVING COUNT(*) > 5
)
Upvotes: 0