Reputation: 917
I have problem in writing SQL in SQL Server. Here is the case, I have three tables named User
, Client
, and UserClient
. Below are the sample of the table content
CLIENT
idClient | client
____________________________
1 | Client A
2 | Client B
3 | Client C
USER
idUser | User
____________________________
1 | User A
2 | User B
3 | User C
USERCLIENT
idUserClient | idUser | idClient
____________________________________
1 | 1 | 1
2 | 1 | 2
3 | 2 | 1
4 | 2 | 3
5 | 3 | 1
I need a query to show user with idClient = 1
AND only have one client from USERCLIENT
table. As shown in the sample above, the result of the query should be
idUserClient | idUser | idClient
_________________________________________
5 | 3 | 1
Upvotes: 2
Views: 1607
Reputation: 77657
This will show users that are associated with the client idClient = 1
and only that client:
SELECT
MAX(idUserClient) AS idUserClient,
idUser,
MAX(idClient) AS idClient
FROM USERCLIENT
GROUP BY idUser
HAVING COUNT(*) = 1
AND COUNT(CASE idClient WHEN 1 THEN 1 END) = 1
The HAVING
clause checks that a group of rows for a user contains exactly one row and among 'them' there's exactly one row where idClient = 1
.
Alternatively, SQL Server 2008 would allow you to do something like this:
WITH ranked AS (
SELECT
*,
rnk = ROW_NUMBER() OVER (
PARTITION BY idUser
ORDER BY CASE idClient WHEN 1 THEN 1 ELSE 0 END, idClient
)
FROM USERCLIENT
)
SELECT
idUserClient,
idUser,
idClient
FROM ranked
WHERE rnk = 1
AND idClient = 1
The CTE ranks the rows in USERCLIENT
in such a way that if a user is associated with idClient = 1
and no other client, the corresponding row is ranked as 1, otherwise the row with idClient = 1
(if such one is present) gets a different rank. Therefore, when selecting from the CTE, you simply need to filter on rnk = 1 AND idClient = 1
.
Upvotes: 0
Reputation: 3972
BINGO!
SELECT * FROM USERCLIENT WHERE iduser IN
(SELECT iduser FROM USERCLIENT GROUP BY iduser HAVING COUNT(iduser)=1)
Upvotes: 1
Reputation: 3318
This worked for me...
with cte AS
(
SELECT 1 AS idUserClient, 1 AS idUser, 1 AS idClient
UNION
SELECT 2 AS idUserClient, 1 AS idUser, 2 AS idClient
UNION
SELECT 3 AS idUserClient, 2 AS idUser, 1 AS idClient
UNION
SELECT 4 AS idUserClient, 2 AS idUser, 3 AS idClient
UNION
SELECT 5 AS idUserClient, 3 AS idUser, 1 AS idClient
)
SELECT * FROM cte c1
WHERE
idUserClient IN
(
SELECT MIN(c2.idUserClient) FROM cte c2 GROUP BY c2.idUser HAVING COUNT(c2.idUser) = 1
)
Upvotes: 1
Reputation: 17146
Given the data you mention, you can get the result you are looking for in two ways.
select * from userclient where idUser = 3
or
select * form userClient where idUser = 3 and idClient = 1
I'm not sure what you really want, but these two cases produces the result.
What do you got to query with?
Upvotes: 0
Reputation: 17048
Assuming that (idUser, idClient)
is an unique index:
SELECT USERCLIENT.idUser
FROM USER
INNER JOIN USERCLIENT
ON USER.idUser = USERCLIENT.idUser
WHERE USERCLIENT.idClient = 1
GROUP BY USERCLIENT.idUser
HAVING COUNT(*) = 1
Upvotes: 0