Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/postgresql/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用SUM的SQL查询问题_Sql_Postgresql - Fatal编程技术网

使用SUM的SQL查询问题

使用SUM的SQL查询问题,sql,postgresql,Sql,Postgresql,我的数据库模式的相关部分如下所示(RubyonRails迁移代码,但应该易于阅读): 我想要一个查询,它返回一个用户列表,用户列表按自某个日期以来收到的性能点数总数排序。请注意,一个“性能点”行不等于一个点,我们需要将“点”相加 到目前为止,我的查询如下所示: SELECT u.id, u.slug, SUM(pp.points) AS total FROM users u JOIN performance_points pp ON pp.user_id = u.id JOIN team_mem

我的数据库模式的相关部分如下所示(RubyonRails迁移代码,但应该易于阅读):

我想要一个查询,它返回一个用户列表,用户列表按自某个日期以来收到的性能点数总数排序。请注意,一个“性能点”行不等于一个点,我们需要将“点”相加

到目前为止,我的查询如下所示:

SELECT u.id, u.slug, SUM(pp.points) AS total
FROM users u
JOIN performance_points pp ON pp.user_id = u.id
JOIN team_memberships tm ON tm.team_id = pp.team_id AND tm.user_id = pp.user_id
WHERE (pp.date > '2015-08-02 13:57:14.042221')
GROUP BY pp.id, u.id
ORDER BY total DESC
LIMIT 50
前三个结果是:

"id","slug","total"
32369,"andreas-jensen-9de10dec-0f88-427f-b135-62cebea611c8",245
23752,"kenneth-kjaerstad",95
34179,"marius-mork-rydal",93
为了检查结果是否正确,我计算每个用户的分数。然而,第二个似乎是错误的。我使用Kenneth的id运行此查询:

SELECT SUM(performance_points.points)
FROM performance_points
WHERE performance_points.user_id = 23752
  AND (date > '2015-08-02 13:57:14.042221')
我得到:
84
。查看Kenneth的所有性能点:

SELECT performance_points.points
FROM performance_points
WHERE performance_points.user_id = 23752
  AND (date > '2015-08-02 13:57:14.042221')
我们得到:

"points"
-10
1
-2
95
-10+1-2+95实际上是84,所以我不知道第一个查询是怎么回事。为什么总数是95


我正在运行PostgreSQL 9.3.5版

请尝试下面的查询,并让我们知道答案(如果可行):

SELECT u.id, u.slug, SUM(pp.points) AS total
FROM users u
INNER JOIN (select user_id,date,team_id, SUM(points) as points from performance_points group by user_id,date,team_id) pp ON pp.user_id = u.id
INNER JOIN (select team_id, user_id from team_memberships group by team_id, user_id) tm ON tm.team_id = pp.team_id AND tm.user_id = pp.user_id
WHERE (pp.date > '2015-08-02 13:57:14.042221')
GROUP BY u.id, u.slug
ORDER BY total DESC
LIMIT 50
;

请尝试下面的查询,并让我们知道答案(如果可行):

SELECT u.id, u.slug, SUM(pp.points) AS total
FROM users u
INNER JOIN (select user_id,date,team_id, SUM(points) as points from performance_points group by user_id,date,team_id) pp ON pp.user_id = u.id
INNER JOIN (select team_id, user_id from team_memberships group by team_id, user_id) tm ON tm.team_id = pp.team_id AND tm.user_id = pp.user_id
WHERE (pp.date > '2015-08-02 13:57:14.042221')
GROUP BY u.id, u.slug
ORDER BY total DESC
LIMIT 50
;

在看不到所有数据的情况下,有点难以猜测,但可能需要一个CTE来预处理性能点:

with pp_totals as (
  select user_id, sum (points) as points
  from performance_points
  where date > '2015-08-02 13:57:14.042221'
  group by user_id
)
SELECT
  u.id, u.slug, pp.points AS total
FROM
  users u
  JOIN pp_totals pp ON pp.user_id = u.id
  JOIN team_memberships tm ON tm.user_id = u.user_id
ORDER BY pp.points DESC
limit 50

如果这样做不起作用,您能否创建一个SQL FIDLE并将其发布到您的问题中?

在没有看到所有数据的情况下,有点难以猜测,但可能需要一个CTE来预处理性能点:

with pp_totals as (
  select user_id, sum (points) as points
  from performance_points
  where date > '2015-08-02 13:57:14.042221'
  group by user_id
)
SELECT
  u.id, u.slug, pp.points AS total
FROM
  users u
  JOIN pp_totals pp ON pp.user_id = u.id
  JOIN team_memberships tm ON tm.user_id = u.user_id
ORDER BY pp.points DESC
limit 50

如果这样做不行,您能否创建一个SQL FIDLE并将其发布到您的问题中?

如果每个用户的
slug
是唯一的:

SELECT u.id, u.slug, SUM(pp.points) AS total
FROM users u
JOIN performance_points pp
ON u.id = pp.user_id
WHERE pp.date > '2015-08-02 13:57:14.042221'
GROUP BY u.id, u.slug
ORDER BY total DESC
LIMIT 50
否则,您不能
选择
slug
,因为它不是一个分组列,所以每个组中都有多个值。您希望在
性能点中
按用户id
分组
以获得每个
用户id
总数
,然后
加入
用户
以获得
slug
s

SELECT id, slug, total
FROM users
JOIN (
    SELECT user_id, SUM(points) AS total
    FROM performance_points
    WHERE date > '2015-08-02 13:57:14.042221'
    GROUP BY user_id) t
ON id = user_id
ORDER BY total DESC
LIMIT 50

(不清楚您为什么加入
团队成员
性能点(用户id,团队id)
可能是一个外键,即所有这些对都已经在其中。)

如果
slug
每个用户都是唯一的:

SELECT u.id, u.slug, SUM(pp.points) AS total
FROM users u
JOIN performance_points pp
ON u.id = pp.user_id
WHERE pp.date > '2015-08-02 13:57:14.042221'
GROUP BY u.id, u.slug
ORDER BY total DESC
LIMIT 50
否则,您不能
选择
slug
,因为它不是一个分组列,所以每个组中都有多个值。您希望在
性能点中
按用户id
分组
以获得每个
用户id
总数
,然后
加入
用户
以获得
slug
s

SELECT id, slug, total
FROM users
JOIN (
    SELECT user_id, SUM(points) AS total
    FROM performance_points
    WHERE date > '2015-08-02 13:57:14.042221'
    GROUP BY user_id) t
ON id = user_id
ORDER BY total DESC
LIMIT 50

(不清楚您为什么加入
团队成员
性能点(用户id,团队id)
可能是一个外键,即所有这些对都已经在其中。)

我接受了您的查询并添加了一个过滤器,以限制单个用户。您现在应该看到用户kenneth kjaerstad的四行:

SELECT u.id, u.slug, SUM(pp.points) AS total
FROM
    users u
    JOIN performance_points pp ON pp.user_id = u.id
    JOIN team_memberships tm ON tm.team_id = pp.team_id AND tm.user_id = pp.user_id
WHERE pp.date > '2015-08-02 13:57:14.042221' and u.id = 23752
GROUP BY pp.id, u.id
问题是,这类人把所有其他行都推到了这个列表的最下方,而你从来没有看到除了排名第一的那一行之外,他还有三行

原因是您的分组错误,因为您只需要每个用户的总数
pp.id
事实上对于结果中的每一行都应该是唯一的,并且在该列上有一个group by是毫无意义的

另外,我要注意的是,您加入
团队成员资格
表似乎没有什么目的,除非您需要保证积分表中的每对用户和团队ID都有团队成员资格。以下是修复方法:

SELECT u.id, min(u.slug) as slug, SUM(pp.points) AS total
FROM
    users u
    JOIN performance_points pp ON pp.user_id = u.id
    JOIN team_memberships tm ON tm.team_id = pp.team_id AND tm.user_id = pp.user_id
WHERE pp.date > '2015-08-02 13:57:14.042221'
GROUP BY u.id
ORDER by total desc

这个答案基本上等同于@philipxy和@Hambone的答案。正如您所见,严格来说,不必使用他们选择的某些构造。希望我对出错原因的解释能对您更喜欢的方法有所帮助。

我接受了您的查询,并添加了一个过滤器以限制单个用户。您现在应该看到用户kenneth kjaerstad的四行:

SELECT u.id, u.slug, SUM(pp.points) AS total
FROM
    users u
    JOIN performance_points pp ON pp.user_id = u.id
    JOIN team_memberships tm ON tm.team_id = pp.team_id AND tm.user_id = pp.user_id
WHERE pp.date > '2015-08-02 13:57:14.042221' and u.id = 23752
GROUP BY pp.id, u.id
问题是,这类人把所有其他行都推到了这个列表的最下方,而你从来没有看到除了排名第一的那一行之外,他还有三行

原因是您的分组错误,因为您只需要每个用户的总数
pp.id
事实上对于结果中的每一行都应该是唯一的,并且在该列上有一个group by是毫无意义的

另外,我要注意的是,您加入
团队成员资格
表似乎没有什么目的,除非您需要保证积分表中的每对用户和团队ID都有团队成员资格。以下是修复方法:

SELECT u.id, min(u.slug) as slug, SUM(pp.points) AS total
FROM
    users u
    JOIN performance_points pp ON pp.user_id = u.id
    JOIN team_memberships tm ON tm.team_id = pp.team_id AND tm.user_id = pp.user_id
WHERE pp.date > '2015-08-02 13:57:14.042221'
GROUP BY u.id
ORDER by total desc

这个答案基本上等同于@philipxy和@Hambone的答案。正如您所见,严格来说,不必使用他们选择的某些构造。希望我对出错原因的解释能对您更喜欢的方法有所帮助。

我发现查询实际上没有问题,而是数据有问题。有些用户在多个团队中不止一次出现问题。

我发现查询实际上没有问题,但数据有问题。有些用户不止一次在多个团队中,并且出现问题。

是否所有性能点行都属于同一个团队成员?对于此用户,它们都是,但情况可能并非总是如此。用户可以在多个团队中,并从每个团队中获得分数。只需将原始查询中的
select…
替换为
select*
并删除
groupby
子句,我相信您会发现问题。请将示例输入、输出和所需输出以及表格约束编辑到您的问题中。在帮助中心了解MCVE。你为什么加入团队成员?性能点(用户id、团队id)不是其中的FK吗?是否所有性能点行都属于同一团队成员?对于此用户,它们是,但可能并非总是如此。用户可以在多个团队中,并从每个团队中获得分数。只需将原始查询中的
select…
替换为
select*
并删除
gr