Knex 子查询对来自第二个 table 的数据求和
Knex subquery to sum data from 2nd table
我正在尝试使用 knex 编写一个查询来对每个问题的投票求和,但没有得到正确的总和。我可以在 SQL 中编写子查询,但似乎无法将它们拼凑在一起。我是一名学生,不确定我是否对 Knex 做错了什么,或者我的基本逻辑是否有误。在此先感谢您的帮助!
我的 knex 查询如下所示
return knex
.from('question')
.select(
'question.id AS question_id',
knex.raw(
`count(DISTINCT vote) AS number_of_votes`, //this returns the number_of_votes for each question_id as expected
),
knex.raw(
`sum(vote.vote) AS sum_of_votes`, //something wrong here... E.g., question_id 1 has 3 down votes so the sum should be -3, however I am getting -9
),
)
.leftJoin('user', 'question.user_id', 'user.id')
.leftJoin('vote', 'question.id', 'vote.question_id')
.groupBy('question.id', 'user.id');
有 3 个表格如下所示:
用户
- 编号
- user_name
问题
- id
- 标题
- body
- user_id(FK 引用 user.id)
投票
- question_id(FK 引用 question.id)
- user_id(FK 引用 user.id)
- 投票(-1 或 1)
- 主键(question_id、user_id)
我设法将查询编写为 stand-alone SQL 查询并验证它按预期工作。这就是我在上面的 knex 查询中试图完成的:
SELECT question.id, sum(vote.vote) AS sum_of_votes FROM question LEFT JOIN vote ON question.id = vote.question_id GROUP BY question.id;
经过几个小时的努力,我终于明白了。这是解决方案:
return knex
.from('question')
.select(
'question.id AS question_id',
knex.raw(
`count(DISTINCT vote) AS number_of_votes`,
),
knex.raw(
`SELECT sum(vote) from vote WHERE question_id = question.id GROUP BY question_id) AS sum_of_votes`
)
.leftJoin('user', 'question.user_id', 'user.id')
.leftJoin('vote', 'question.id', 'vote.question_id')
.groupBy('question.id', 'user.id');
所以,大体上你的 SQL 查询是正确的(修正了几个拼写错误后),尽管 @felixmosh 指出其中没有用户信息:可能很难弄清楚谁投票了为了什么!但也许您不需要它来实现您的目的。
您发布的解决方案可以解决问题,但可能不是最有效的作业查询,因为它涉及一个子查询和多个连接。这是它生成的 SQL:
SELECT "question"."id" AS "question_id",
count(DISTINCT vote) AS number_of_votes,
(
SELECT sum(vote) FROM vote
WHERE question_id = question.id
GROUP BY question_id
) AS sum_of_votes
FROM "question"
LEFT JOIN "user" ON "question"."user_id" = "user"."id"
LEFT JOIN "vote" ON "question"."id" = "vote"."question_id"
GROUP BY "question"."id", "user"."id";
我们可以采用更简单的方法来获取相同的信息。这个怎么样?
SELECT question_id,
count(vote) AS number_of_votes,
sum(vote) AS sum_of_votes
FROM vote
GROUP BY question_id;
这会获取您要查找的所有信息,而无需连接任何表或使用子查询。它还避免了 DISTINCT
,这可能导致错误地计算票数。生成此类查询的 Knex 如下所示:
knex("vote")
.select("question_id")
.count("vote AS number_of_votes")
.sum("vote AS sum_of_votes")
.groupBy("question_id")
只有在从这些表中查找更多信息(例如用户名或问题标题)时,才真正需要在此处联接表。
我正在尝试使用 knex 编写一个查询来对每个问题的投票求和,但没有得到正确的总和。我可以在 SQL 中编写子查询,但似乎无法将它们拼凑在一起。我是一名学生,不确定我是否对 Knex 做错了什么,或者我的基本逻辑是否有误。在此先感谢您的帮助!
我的 knex 查询如下所示
return knex
.from('question')
.select(
'question.id AS question_id',
knex.raw(
`count(DISTINCT vote) AS number_of_votes`, //this returns the number_of_votes for each question_id as expected
),
knex.raw(
`sum(vote.vote) AS sum_of_votes`, //something wrong here... E.g., question_id 1 has 3 down votes so the sum should be -3, however I am getting -9
),
)
.leftJoin('user', 'question.user_id', 'user.id')
.leftJoin('vote', 'question.id', 'vote.question_id')
.groupBy('question.id', 'user.id');
有 3 个表格如下所示:
用户
- 编号
- user_name
问题
- id
- 标题
- body
- user_id(FK 引用 user.id)
投票
- question_id(FK 引用 question.id)
- user_id(FK 引用 user.id)
- 投票(-1 或 1)
- 主键(question_id、user_id)
我设法将查询编写为 stand-alone SQL 查询并验证它按预期工作。这就是我在上面的 knex 查询中试图完成的:
SELECT question.id, sum(vote.vote) AS sum_of_votes FROM question LEFT JOIN vote ON question.id = vote.question_id GROUP BY question.id;
经过几个小时的努力,我终于明白了。这是解决方案:
return knex
.from('question')
.select(
'question.id AS question_id',
knex.raw(
`count(DISTINCT vote) AS number_of_votes`,
),
knex.raw(
`SELECT sum(vote) from vote WHERE question_id = question.id GROUP BY question_id) AS sum_of_votes`
)
.leftJoin('user', 'question.user_id', 'user.id')
.leftJoin('vote', 'question.id', 'vote.question_id')
.groupBy('question.id', 'user.id');
所以,大体上你的 SQL 查询是正确的(修正了几个拼写错误后),尽管 @felixmosh 指出其中没有用户信息:可能很难弄清楚谁投票了为了什么!但也许您不需要它来实现您的目的。
您发布的解决方案可以解决问题,但可能不是最有效的作业查询,因为它涉及一个子查询和多个连接。这是它生成的 SQL:
SELECT "question"."id" AS "question_id",
count(DISTINCT vote) AS number_of_votes,
(
SELECT sum(vote) FROM vote
WHERE question_id = question.id
GROUP BY question_id
) AS sum_of_votes
FROM "question"
LEFT JOIN "user" ON "question"."user_id" = "user"."id"
LEFT JOIN "vote" ON "question"."id" = "vote"."question_id"
GROUP BY "question"."id", "user"."id";
我们可以采用更简单的方法来获取相同的信息。这个怎么样?
SELECT question_id,
count(vote) AS number_of_votes,
sum(vote) AS sum_of_votes
FROM vote
GROUP BY question_id;
这会获取您要查找的所有信息,而无需连接任何表或使用子查询。它还避免了 DISTINCT
,这可能导致错误地计算票数。生成此类查询的 Knex 如下所示:
knex("vote")
.select("question_id")
.count("vote AS number_of_votes")
.sum("vote AS sum_of_votes")
.groupBy("question_id")
只有在从这些表中查找更多信息(例如用户名或问题标题)时,才真正需要在此处联接表。