2012-09-04 71 views
1
SELECT cf.FK_collection, c.collectionName, 
    uf.FK_userMe, uf.FK_userYou, 
    u.userId, u.username 
FROM userFollows as uf 
INNER JOIN collectionFollows as cf ON uf.FK_userMe = cf.FK_user 
INNER JOIN collections as c ON cf.FK_collection = c.collectionId 
INNER JOIN users as u ON uf.FK_userYou = u.userId 
WHERE uf.FK_userMe = 2 

嘿家伙。MySQL - 修复多条记录

我试图做这个查询,它当然不会按我想要的那样做,因为它返回多行,这在某种程度上是我想要的,但事实并非如此。让我试着解释一下:

我试图同时获得collectionFollows和userFollows,以显示用户在网站上的活动。但是,当这样做时,即使用户只跟随1,我也会有多行userFollows。这是因为我遵循多个collectionFollow。

所以,当我告诉我的结果将返回这样的:

John is following 'webdesign' 
John is following 'Lisa' 
John is following 'programming' 
John is following 'Lisa' 

我想知道如果我必须做出多个查询或者使用子查询?最佳做法是什么?那么我将如何编写查询呢?

+1

如果你知道这个问题已被问了十亿次,你一定找到了至少一百万个答案。 – GolezTrol

+0

@GolezTrol如果我有我不会写这个问题。我也在问什么是最好的做法,而不是其他问题。 – skolind

+0

好的。最佳做法是首先编写一个可行的查询(您不知道),然后您可以优化。我试图在我的回答中解决这个问题。 – GolezTrol

回答

3

实际上,您将两个完全无关的查询组合在一起。我会把它们作为单独的查询,特别是因为你也这样报告它们。如果您愿意,可以使用UNION ALL来组合这些查询。通过这种方式,无论项目的类型如何,您都只需要列出所关注项目的名称。如果你愿意,你也可以指定。

SELECT 
    cf.user, 
    cf.FK_collection as followItem, 
    c.collectionName as followName, 
    'collection' as followType 
FROM collectionFollows as cf 
INNER JOIN collections as c ON cf.FK_collection = c.collectionId 
WHERE cf.user = 2 
UNION ALL 
SELECT 
    uf.FK_userMe, 
    u.userId, 
    u.username 
    'user' as followType 
FROM userFollows as uf 
INNER JOIN users as u ON uf.FK_userYou = u.userId 
WHERE uf.FK_userMe = 2 

另一种方法是用PHP来筛选唯一值,但即使如此,你的查询将失败。由于内部连接,如果用户只关注其他用户或仅关注集合,则不会得到任何结果。您至少需要其中一个才能获得任何结果。 您可以将INNER JOIN更改为LEFT JOIN,但是您仍然必须后处理查询来过滤双打并过滤掉NULL值。

UNION ALL很快。它只是将两个查询结果粘贴在一起而没有进一步处理。这与UNION不同,UNION也会过滤两次(如DISTINCT)。在这种情况下,它不是必需的,因为我假设用户只能跟踪集合或其他用户一次,因此这些查询将永远不会返回重复的记录。如果确实如此,UNION ALL会做得很好,而且会比UNION更快。

除了UNION ALL,两个单独的查询也没问题。

+0

谢谢你的回答,我会回来的。谢谢! – skolind

+0

这是完美的。非常感谢。一个非常有用的答案!我现在将阅读有关UNION的全部内容以及它如何工作,以便我不只是复制粘贴您的答案。谢谢! – skolind

+0

'UNION ALL',而不是'UNION'。他们是不同的! :) – GolezTrol