从表中选择一次出现的用户

时间:2018-02-06 08:12:20

标签: mysql

我有一个表订单:

|--------------------|-----------------|------------|
|      user_id       |    article_id   |  Name      |
|--------------------|-----------------|------------|
|         1          |         39      |  John      |
|         1          |         39      |  John      |
|         2          |         39      |  Mike      |
|         2          |         19      |  Mike      |
|         3          |         39      |  Dave      |
|--------------------|-----------------|------------|

如何只选择具有article_id = 39的用户,无论多少次,但是只发生一次。 我需要选择用户John和用户Dave,但不要选择Mike。 Mike有article_id 39,但他也有article_id = 19。 该查询应该返回用户John和Dave。

我试过这个问题:

SELECT * FROM orders AS o where o.article_id = 39
GROUP BY o.user_id HAVING COUNT(o.article_id) > 0

但它返回所有三个用户。我不需要用户Mike。

3 个答案:

答案 0 :(得分:6)

HAVING子句中使用条件聚合:

SELECT user_id, Name
FROM orders
GROUP BY user_id, Name
HAVING SUM(CASE WHEN article_id <> 39 THEN 1 ELSE 0 END) = 0;

注意:您的表未规范化,用户信息属于单独的用户表。我可以通过在GROUP BY子句中包含名称来解决这个问题,但理所当然我们应该通过user_id聚合。

答案 1 :(得分:3)

蒂姆上面的答案是获得你所寻找的最有效的方法。另一个解决方案是使用嵌套查询。

首先,您选择所有没有article_id 39的用户:

SELECT user_id FROM orders WHERE article_id <> 39

然后选择article_id为39且不在此列表中的用户。总的来说,查询将是:

SELECT user_id FROM orders WHERE article_id = 39 
AND user_id NOT IN (SELECT user_id from orders where article_id <> 39)

再次,蒂姆和约翰已经发布的答案更有效,更好。我只是在学习SQL时发现这样的查询更易于阅读/理解。

答案 2 :(得分:1)

另一种方法是使用MIN()MAX()

SELECT  user_id
FROM    orders
GROUP   BY Name
HAVING  MIN(article_id) = MAX(article_id)
        AND MIN(article_id) = 39