【问题标题】:SQL join with count not workingSQL加入计数不起作用
【发布时间】:2011-03-18 16:03:08
【问题描述】:
SELECT p.PostPID, p.PostUID, p.PostText, p.PostTime, u.UserUID, u.UserName, u.UserImage, u.UserRep,
    (
        SELECT COUNT(f.FlagTime)
            FROM Flags as f 
                JOIN Posts as p 
                ON p.PostPID = f.FlagPID
    ) as PostFlags
    FROM Posts AS p
        JOIN Users AS u
        ON p.PostUID = u.UserUID
    ORDER BY PostTime DESC
    LIMIT 0, 30

我有这个查询,但我不知道为什么,但这段代码似乎不起作用,它返回查询就像这样:

SELECT p.PostPID, p.PostUID, p.PostText, p.PostTime, u.UserUID, u.UserName, u.UserImage, u.UserRep,
    (
        SELECT COUNT(f.FlagTime)
            FROM Flags as f 
    ) as PostFlags
    FROM Posts AS p
        JOIN Users AS u
        ON p.PostUID = u.UserUID
    ORDER BY PostTime DESC
    LIMIT 0, 30

我做错了什么?

【问题讨论】:

  • 能否提供样本数据、当前输出和期望输出?
  • 查理,这有点搞笑 - 你有一个你不理解的查询,因为它的行为与 所期望的不同。为了解释你对它的期望,你给我们另一个查询,希望什么?在您的问题的读者中,会有人确切地了解您如何误解自己的第一个查询并准确了解您如何解释您的第二个查询。由于娱乐价值,没有投票给你。

标签: mysql sql join subquery


【解决方案1】:
SELECT p.PostPID, p.PostUID, p.PostText, p.PostTime, u.UserUID, u.UserName, u.UserImage, u.UserRep,
    (
        SELECT COUNT(f.FlagTime)
            FROM Flags as f 
                JOIN Posts as p1
                ON p1.PostPID = f.FlagPID
                where p1.PostPID = p.PostPID
    ) as PostFlags
FROM Posts AS p
    JOIN Users AS u
    ON p.PostUID = u.UserUID
ORDER BY PostTime DESC
LIMIT 0, 30

编辑:

我觉得这样会更好:

SELECT p.PostPID, p.PostUID, p.PostText, p.PostTime, u.UserUID, u.UserName, u.UserImage, u.UserRep,
    count(f.FlagTime) as PostFlags

FROM Posts AS p
JOIN Users AS u ON p.PostUID = u.UserUID
left join Flags f on p.PostPID = f.FlagPID

group by p.PostPID, p.PostUID, p.PostText, p.PostTime, u.UserUID, u.UserName, u.UserImage, u.UserRep

ORDER BY PostTime DESC
LIMIT 0, 30

【讨论】:

  • Clodoaldo 的两个版本应该产生相同的结果(假设 PostPID 是唯一的)但我不推荐第二个版本;一个人可以分组的字段数量通常是有限的。相关子查询版本通常被认为是更好的做法。
  • 关联子查询中的联接是多余的,如果 PostPID 在 [Posts] 中不是唯一的,则结果将重复。我只是删除连接并放入 WHERE f.FlagPID = p.PostPID (引用 [Posts] 表的主查询实例。
  • @Dems 是的,您对冗余是正确的。相反,鉴于缺乏信息,我假设名为 somethingID 的列应该是唯一的。您能否在 group by 中引用该字段限制的来源?
【解决方案2】:

没有示例数据、示例输出和所需输出的描述,很难确定您需要什么。

然而,我注意到的是,您的子查询 (PostFlags) 包含表 Posts,您的主查询也是如此。他们甚至共享同一个别名。


据此,我推断你想得到两件事之一......

  1. 所有帖子的所有标志的计数
    这将为您的结果中的每条记录提供相同的值

  2. 当前帖子的所有标志的计数
    这将为结果中的每条记录提供不同的值


如果您想要版本一,我会更改子查询的别名。不要使用“P”,而是使用“Px”或其他东西。我不认为这必然会改变任何东西,但是使用与主查询相同的别名可能会使人类读者感到困惑,更不用说 RDBMS。


如果您想要第二版,则无需在子查询中包含联接。相反,您可以执行以下操作...

SELECT
  p.PostPID, p.PostUID, p.PostText, p.PostTime, u.UserUID, u.UserName, u.UserImage, u.UserRep,
  (
      SELECT COUNT(FlagTime)
      FROM Flags
      WHERE FlagPID = p.PostPID
  ) as PostFlags
FROM
  Posts AS p
JOIN
  Users AS u
    ON p.PostUID = u.UserUID
ORDER BY
  PostTime DESC
LIMIT 0, 30

where 子句现在从主查询中引用 Posts 表。这变成了一个 Correlated-Sub-Query - 结果取决于另一个表中字段的值。


如果这些都不是你需要的,请举例说明;
- 示例数据
- 示例结果
- 预期结果
- 描述为什么这些是预期的

【讨论】:

    猜你喜欢
    • 2011-12-12
    • 1970-01-01
    • 1970-01-01
    • 2013-03-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多