【问题标题】:How to implement a subquery to select rows that match two out of three topics?如何实现子查询来选择匹配三个主题中的两个的行?
【发布时间】:2013-11-11 04:00:25
【问题描述】:

如果没有集合运算符,我如何才能找到任何涵盖三个不同 SQL 系统中的两个的书籍。我正在使用三个主题 id 'SSRV'、'ORA'、'MySQL' 并且需要输出任意三个中的 2 个。例如,这本书可能有一个主题 SSRV 和一个 ORA 主题,但没有 MySQL。这些主题的任意两种组合都足以通过我们的过滤器。

我想显示符合此测试的书籍的 book_id 和标题。

  SELECT book_id
       , title
    FROM a_bkinfo.books B
   WHERE book_id IN (
       SELECT book_id
         FROM a_bkinfo.book_topics BT
    WHERE topic_id = 'SSRV' )
  AND book_id IN (
       SELECT book_id
         FROM a_bkinfo.book_topics BT
    WHERE topic_id = 'ORA' )
  AND book_id IN (
       SELECT book_id
         FROM a_bkinfo.book_topics BT
    WHERE topic_id = 'MySQL' )
  AND book_id IN (
        SELECT COUNT(*) 
                   FROM (  
                       SELECT book_id
                           ,  count(topic_id) AS topics
                         FROM a_bkinfo.book_topics BT 
                        GROUP BY book_id
                        HAVING count(topic_id) = 2
                        ) t 
              ;  

更新版本:

   SELECT book_id
 , title
 FROM a_bkinfo.books B
 WHERE book_id IN (
       SELECT book_id
         FROM a_bkinfo.book_topics BT
    WHERE topic_id ='SSRV'
        OR topic_id ='ORA' )
AND book_id IN (
        SELECT book_id
          FROM a_bkinfo.book_topics BT
    WHERE topic_id ='SSRV' 
        OR topic_id ='MySQL')
AND book_id IN (
        SELECT book_id
          FROM a_bkinfo.book_topics BT
    WHERE topic_id ='ORA' 
        OR topic_id ='MySQL');

【问题讨论】:

  • 更新后的查询还将同时返回所有 3 种类型的书籍
  • 所以你明确地只希望 2 匹配,但如果所有 3 匹配则失败?如果一本书涵盖了我正在寻找的所有 3 个主题,我为什么要排除它。您还提到没有“设置”运算符...您指的是 [where topic_id in ('ORA', 'SSRV', 'MySQL')] 如果是这样,为什么在查询中这是一件坏事?

标签: mysql subquery logical-operators


【解决方案1】:
SELECT b.book_id, b.title, COUNT(*) FROM books b
INNER JOIN book_topics bt ON (b.book_id = bt.book_id)
GROUP BY b.book_id, b.title
HAVING COUNT(*) = 2

如果 book_topics 中的每个书-主题关系只有一行,这将起作用。这些对也必须是唯一的。如果您的数据不符合要求,则需要更复杂的查询。
更新
因为 book_id 是唯一的唯一标识符,所以这是新版本:

SELECT b.book_id FROM books b
INNER JOIN book_topics bt ON (b.book_id = bt.book_id)
GROUP BY b.book_id
HAVING COUNT(topic_id) = 2

要求同上。

【讨论】:

  • 标题属于bt book_topics。在那种情况下,我是否只需使用相关子查询和上面的输入连接两个表?如果是这样,那会是什么样子?
  • @user2966637 同一个 book_id 的书名总是相同的吗?
  • 查看我的更新版本。这有意义吗?输出看起来正确。
  • 同一个书名的不同标题?您能否根据属性唯一性和表关系更详细地描述您的数据模型?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-02-03
  • 1970-01-01
  • 2020-06-24
相关资源
最近更新 更多