为什么这个双JOIN工作,但这个类似的不起作用?

时间:2014-06-10 22:15:04

标签: sql join

这适用于Rails应用,但我只是发布了SQL。

所以,这是我的理智测试。它工作,并返回相同模型的两个副本。如果我不包含多个模型的where多个副本,则会返回。

SELECT \"outlets\".* 
FROM \"outlets\" 
INNER JOIN \"comments\" 
ON \"comments\".\"commentable_id\" = \"outlets\".\"id\" 
AND \"comments\".\"commentable_type\" = 'Outlet'
INNER JOIN \"statistics\" 
ON \"statistics\".\"statable_id\" = \"outlets\".\"id\" 
AND \"statistics\".\"statable_type\" = 'Outlet' 
WHERE (\"outlets\".\"id\" = '1')

#=> [#<Outlet id: 1...>, #<Outlet id: 1...>]
# without the where I get back something like
# [...id: 1, id: 1, id: 5, id: 5, id: 5, id: 5 ]

我不确定如何编写它,因此它只返回一个值(不使用distinct)。但那可能是我的下一个问题。

这是我试图开展工作的SQL。我还尝试明确指定INNER并颠倒均等的顺序:

SELECT \"followings\".* 
FROM \"followings\"
JOIN \"outlets\"
ON \"followings\".\"followable_id\" = \"outlets\".\"id\"
AND \"followings\".\"followable_type\" = 'Outlet'
JOIN \"people\"
ON \"followings\".\"followable_id\" = \"people\".\"id\"
AND \"followings\".\"followable_type\" = 'Person'
WHERE (\"followings\".\"user_id\" = '1')

#=> []
# Exact same result from removing the WHERE clause

每个联接都有记录。如果我单独加入任何一个表,它们都返回我专门创建的结果来测试我的SQL。所以:

SELECT \"followings\".* 
FROM \"followings\" 
INNER JOIN \"people\"
ON \"followings\".\"followable_id\" = \"people\".\"id\"
AND \"followings\".\"followable_type\" = 'Person' 
WHERE (\"followings\".\"user_id\" = '1')

#=> [<Following id: 2...>]
# And id: 1 for joining on outlets without people

在这里让我感到困惑的部分是工作版本和不工作版本基本相同,但我不明白为什么它应该在一个地方而不是另一个地方工作

编辑:

进度,将JOIN的{​​{1}}更改为followings将返回所需的结果。但是,为什么它同时适用于LEFT OUTER JOIN outlets.id= commentable_id

而且,我只是尝试将= statable_id更改为LOJ,并且返回的结果列表大约是最长SQL调用I&#中出口表本身长度的两倍。 39;曾见过。因此,虽然它的进展如此,但我认为这不是一般解决方案。

编辑2:

感谢用可接受的答案测试了一些东西,我意识到我选择的统计数据是“误导”#34;结果因为每个插座都有统计数据。当我更改为更好的测试表(例如outlets)时,followings的行为类似。 JOIN方法返回预期的条目

2 个答案:

答案 0 :(得分:1)

我想,这应该可以让你得到你想要的东西。您可以单独获取这两个列表,然后将它们与UNION结合使用。

SELECT followings.*
FROM followings
JOIN outlets ON followings.followable_id = outlets.id
WHERE followable_type = 'Outlet'

UNION

SELECT followings.*
FROM followings
JOIN people ON followings.followable_id = people.id
WHERE followable_type = 'Person'

答案 1 :(得分:0)

您的问题查询,如下所示进行更改。使\"followings\".\"followable_type\"成为OR条件(已使用IN运算符)。我也把条件从JOIN移到了WHERE子句。

SELECT \"followings\".* 
FROM \"followings\"
JOIN \"outlets\"
ON \"followings\".\"followable_id\" = \"outlets\".\"id\"
JOIN \"people\"
ON \"followings\".\"followable_id\" = \"people\".\"id\"
WHERE (\"followings\".\"user_id\" = '1')
AND \"followings\".\"followable_type\" IN ('Outlet','Person')

你也可以说

WHERE (\"followings\".\"user_id\" = '1')
AND (
\"followings\".\"followable_type\" = 'Outlet'
 OR 
\"followings\".\"followable_type\" = 'Person'
  )

修改

将条件添加到JOIN本身,不需要WHERE然后

SELECT \"followings\".* 
FROM \"followings\"
JOIN \"outlets\"
ON \"followings\".\"followable_id\" = \"outlets\".\"id\"
AND \"followings\".\"followable_type\" IN ('Outlet','Person')
AND (\"followings\".\"user_id\" = '1')
JOIN \"people\"
ON \"followings\".\"followable_id\" = \"people\".\"id\"