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

大家好。

我正在尝试进行此查询,它当然不会按我的意愿执行,因为它返回多行,这在某种程度上是我想要的,但事实并非如此。让我试着解释一下:

我试图同时获取 collectionFollows 和 userFollows,以显示网站上的用户活动。但是这样做时,即使用户只关注 1,我也会从 userFollows 获得多行。发生这种情况是因为我关注了多个 collectionFollows。

所以当我显示我的结果时,它会像这样返回:

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

我想知道我是否必须进行多个查询或使用子查询?什么是最佳实践?那么我将如何编写查询?

4

1 回答 1

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 之外,两个单独的查询也可以。

于 2012-09-04T06:43:43.693 回答