sql - 为什么这个简单的 SQL 查询不起作用?

标签 sql sql-server

所以我正在使用 SQL Server 2008 并且我有这个查询应该很简单,但由于某种原因不起作用。基本上是这样的:

SELECT TOP 10
    u.Id                AS "UserId",
    u.CreationDate      AS "Member since",
    AVG(q.Score)        AS "Average Question Rating",  
    COUNT(q.Id)         AS "N. of Questions posted by the agent",
    AVG(a.Score)        AS "Average Answer Rating",  
    COUNT(a.Id)         AS "N. of Answers posted by the agent"
FROM    
        Users u, 
        Answers a, 
        Questions q
WHERE q.OwnerUserId = u.Id
AND a.OwnerUserId = u.Id
GROUP BY u.Id, u.CreationDate

当我只处理 Answers 表或 Questions 表时,一切正常。但是,一旦我尝试同时执行这两项操作(如上面的查询),COUNT 就根本不起作用。我得到的是 COUNT(a.Id) 与 COUNT(q.Id) 相同。所以我试着减少我的查询,看看有什么问题,我意识到我只需要在使用另一个表时将 Questions 或 Answers 表(即使没有在任何地方使用它们)添加到 FROM 子句中,一切都被破坏了。

我确信这是我忽略的可笑的微不足道的事情,但这让我发疯了,如果有人能指出哪里出了问题,我将不胜感激。提前谢谢你。

最佳答案

您没有正确加入 AnswersQuestions 以进行聚合。在 AnswersQuestions 之间,结果是一个笛卡尔积(对于每个用户,每个答案都与每个问题相结合)

纠正此问题的最简单方法是在子查询中执行聚合:

SELECT TOP 10
    u.Id                AS "UserId",
    u.CreationDate      AS "Member since",
    ISNULL((SELECT AVG(Score) FROM Answers   WHERE OwnerUserId = u.Id), 0)
                        AS "Average Question Rating",  
           (SELECT COUNT(*)   FROM Answers   WHERE OwnerUserId = u.Id)        
                        AS "N. of Questions posted by the agent",
    ISNULL((SELECT AVG(Score) FROM Questions WHERE OwnerUserId = u.Id), 0)
                        AS "Average Answer Rating",  
           (SELECT COUNT(*)   FROM Questions WHERE OwnerUserId = u.Id)
                        AS "N. of Answers posted by the agent"
FROM  Users u

或者使用连接:

SELECT TOP 10
     u.Id                AS "UserId",
     u.CreationDate      AS "Member since",
     ISNULL(q.a, 0)      AS "Average Question Rating",  
     ISNULL(q.c, 0)      AS "N. of Questions posted by the agent",
     ISNULL(a.a, 0)      AS "Average Answer Rating",  
     ISNULL(a.c, 0)      AS "N. of Answers posted by the agent"
FROM Users u
-- If you LEFT JOIN these tables, you'll get also results for users without
-- questions or answers
LEFT OUTER JOIN (SELECT OwnerUserId, AVG(Score) a, COUNT(*) c 
     FROM Questions GROUP BY OwnerUserId) q
     ON  q.OwnerUserId = u.Id
LEFT OUTER JOIN (SELECT OwnerUserId, AVG(Score) a, COUNT(*) c 
     FROM Answers GROUP BY OwnerUserId) a
     ON  a.OwnerUserId = u.Id

我不太了解 SQL Server 的查询优化器,所以我不能说哪个会更快。第一个解决方案可以利用标量子查询缓存,如果在 SQL Server 中可用的话。否则,第二个查询可能执行较少的嵌套循环。

关于sql - 为什么这个简单的 SQL 查询不起作用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10283431/

相关文章:

c# - 在 .net 中管理和关闭动态创建的 SQL 连接

c# - 从 C# AsyncCTP 使用 ExecuteReaderAsync 的任何缺点

sql-server - ISNULL、COALESCE 函数

sql-server - SSIS 获取连接失败。连接可能未正确配置,或者您可能对此连接没有正确的权限

sql - Bigquery - 忽略 NULL 值的列之间的平均值

SQL 计算日期范围内的连续天数

sql - 根据 CASE 和 GROUP BY 结果创建一个新列

mysql - Entity Framework 是否与 SQL Server 绑定(bind)?

sql - 随时间重复消除

mysql - 当多行具有相同日期时,与上一行相比的百分比变化?