【问题标题】:Selecting users from table with one occurence从表中选择一次出现的用户
【发布时间】:2018-02-06 08:12:19
【问题描述】:

我有一张桌子订单:

|--------------------|-----------------|------------|
|      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。

【问题讨论】:

  • 您可以使用联接(一旦您对数据进行了规范化)

标签: mysql


【解决方案1】:

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 进行聚合。

【讨论】:

  • 已标准化。用户数据在单独的表中,为了清楚起见,我只包含了名称列 :)
【解决方案2】:

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

首先,您选择所有没有 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 时,我发现这样编写的查询更容易阅读/理解。

【讨论】:

  • 写得好 +1 ...在某些情况下,这种方法比聚合查询更可取。
  • 我想看看这些解决方案的相对效率的一些证据。你有吗?
  • 也许,这种说法太笼统了,这个解决方案不会那么有效。关于证据,我没有。我的理解是尽可能避免嵌套查询。也许我在这方面错了。有other posts 更详细地讨论了嵌套查询的性能。
【解决方案3】:

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-04-02
    • 2014-01-27
    • 2021-03-21
    • 2018-07-11
    • 1970-01-01
    相关资源
    最近更新 更多