【问题标题】:Join on the same table加入同一张桌子
【发布时间】:2012-10-15 11:49:36
【问题描述】:

作为我正在寻找的示例,请考虑以下示例水果表


id  user_id     fruit           type        

1   43      apple           fresh
2   87      watermelon      fresh
3   99      apple           fresh
4   43      pineapple       dried
5   60      pineapple       dried
6   60      lemon           fresh
7   99      kiwi            fresh   
8   43      mango           fresh   

我想在同一张表中找到所有同时拥有“apple”和“dried”的用户的所有记录(不一定同时在同一行)。同一个用户必须同时具备这两个条件。

我想要返回的是:


id  user_id     fruit           type        

1   43      apple           fresh
4   43      pineapple       dried

我尝试了几种自连接组合:


SELECT distinct f1.*, f2.*
FROM orders f1 FULL JOIN orders f2
ON f1.user_id = f2.user_id
WHERE f1.fruit ILIKE 'apple'
AND f2.type ILIKE 'dried'

但还没有完全正确。

这是针对 Rails 应用程序的,所以我希望能够使用 ActiveRecord 来执行此操作,但如果需要,我会对纯 SQL 感到满意。

关于如何做到这一点的任何建议? TIA

【问题讨论】:

    标签: sql ruby-on-rails join self-join


    【解决方案1】:

    这应该为你做:

    SELECT
        *
    FROM
        Fruits
    WHERE
      (Fruit = 'apple'
    OR Type = 'dried')
    AND
        EXISTS
        (SELECT
            NULL
        FROM 
            FRUITS F1
            INNER JOIN Fruits F2 ON F1.User_ID = F2.User_ID AND F1.Fruit = 'apple' and F2.Type = 'dried'
        WHERE
            Fruits.user_ID = F1.User_ID)
    

    【讨论】:

    • 嗨。与我上面的评论相同:这给了我所有 3 条记录(1、4 和 8),而不是只搜索了 2 条记录(1 和 4)
    • @purplerice 我已经编辑添加了额外的 where 子句。当您说您想要在同一个表中同时拥有苹果和干的所有用户的所有记录时,您并不完全清楚。你没有提到你只想要包含苹果或干的行 - 请参阅此处以获取工作示例sqlfiddle.com/#!2/37dcd/6
    • 谢谢 - 这正是我正在寻找的。抱歉,我不太清楚 - 我给出了我正在寻找的结果,因为它并不总是很容易解释。再次感谢!
    【解决方案2】:
    SELECT
      orders.*
    FROM
      orders
    INNER JOIN
      (SELECT user_id FROM orders WHERE fruit = 'apple' GROUP BY user_id) AS apple_buyers
        ON apple_buyers.user_id = orders.user_id
    INNER JOIN
      (SELECT user_id FROM orders WHERE type  = 'dried' GROUP BY user_id) AS dried_buyers
        ON dried_buyers.user_id = orders.user_id
    

    【讨论】:

    • 感谢您的回复,但差不多。这给了我 user_id 的所有 3 条记录,而不仅仅是特定的 2 条记录(我得到了记录 id #s 1,4 和 8 而不仅仅是 #s 1,4。
    • @purplerice - 只需将WHERE orders.fruit = 'apple' OR orders.type = 'dried' 添加到现有查询中。根据您的索引 (我推荐 [user_id,fruit] 和 [user_id, type] 索引) 和您特定的 RDBMS,不同的查询将执行不同的操作。这可能会或可能不会比 Tobsey 的相关子查询版本更快。您需要使用代表真实环境的数据在真实环境中进行测试。
    • 这也很好用。我选择了首先给出的正确答案,但我希望我也能接受你的答案,而不是仅仅 +1。谢谢你。
    【解决方案3】:
    select  TAB1.id,TAB1.user_id,TAB1.fruit,TAB1.types
    
    FROM 
     (select id,user_id,fruit,types
     from IID T1 WHERE  T1.fruit='apple' OR T1.types ='dried')TAB1
    
      INNER JOIN 
    
     (select user_id,count(user_id) AS CNT_user_id
      from IID T1 WHERE  T1.fruit='apple' OR T1.types ='dried'
      group by user_id
      having count(user_id) >=2)TAB2
    
      ON(TAB1.user_id=TAB2.user_id)
    
     id user_id    fruit        types
     4      43     pineapple    dried
     1      43     apple        fresh
    

    【讨论】:

      【解决方案4】:
      SELECT A.id , A.user_id,A.fruit,A.types  FROM iid A 
      WHERE user_id IN(
          SELECT A.user_id FROM 
          (
              SELECT user_id FROM iid 
              WHERE types='dried'
          )A
       INNER JOIN 
          (
              SELECT user_id FROM iid WHERE fruit = 'apple'
          )B
      ON A.user_id=b.user_id)
      AND ( fruit='apple' OR types='dried')
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2014-01-24
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-10-28
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多