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
嘿伙计们。
我正在尝试进行此查询,它当然不会按照我的意愿执行,因为它返回多行,这在某种程度上是我想要的,但事实并非如此。让我试着解释一下:
我尝试同时获取collectionFollows和userFollows,以显示网站上的用户活动。但是当这样做时,我将从userFollows中获得多行,即使用户只跟随1.这是因为我正在关注多个collectionFollows。
所以当我显示我的结果时,它会像这样返回:
John is following 'webdesign'
John is following 'Lisa'
John is following 'programming'
John is following 'Lisa'
我想知道是否必须进行多次查询或使用子查询?什么是最佳做法?那我怎么写这个查询呢?
答案 0 :(得分: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之外,还有两个单独的查询。