2014-06-10 73 views
1

这是一个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 

这里树桩我的部分是,工作版本和不工作的版本基本上是相同的,但我不明白为什么它应该工作的一个地方,而不是其他

编辑:

进度,将JOINfollowings更改为LEFT OUTER JOIN s将返回所需的结果。但那么为什么它在同一时间outlets.id= commentable_id= statable_id

而且,我只是尝试将outlets更改为LOJ,并且返回的结果列表大约是我看过的最长的SQL调用中outlet个体长度的两倍。所以,虽然这是进步,但我认为这不是一个通用的解决方案。

编辑2:

由于测试的东西出来与接受的答案,我意识到,我的选择统计的是给“误导”的结果,因为每个插座有一个统计。当我改为更好的测试表(例如followings)时,两个JOIN的行为都相似。并且UNION方法返回预期的条目

+0

'followings.followable_type'不能同时出现在第二个查询中'='Outlet''和'='Person''。你是否想用这些“出口”和“人”来进行比较? –

+0

我想到了,但在我的工作示例'outlets.id'' = commentable_id'和'= statable_id'在同一时间 – MCB

回答

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' 
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' 
) 

编辑:

添加的条件加入本身,不需要一个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\" 
+0

因此,这确实会返回一个条目,而不是其他。我很惊讶地看到。另外,如果使用'JOIN'完成这项工作,我会非常喜欢。 – MCB

+0

它只返回'后面的id:1',这个''加入'people'。出于某种原因,他们都忽视了第二个“连接”到“网点”。原始和编辑都是一样的。 – MCB

+0

@MCB,它应该是正确的?根据你的情况WHERE(\“followings \”。\“user_id \”='1')' – Rahul