Postgresql 如何根据knex.js中的第三列将一列拆分为两列?

Postgresql 如何根据knex.js中的第三列将一列拆分为两列?,postgresql,knex.js,Postgresql,Knex.js,我有一项任务,我一直忙得不可开交 所以我有一个表transactions,它有两列bonus和type,比如: bonus | type 20 1 15 -1 我想要的是将一个带有bonus列的查询按type分为两列bonus\u-spend和bonus\u-left 它应该看起来像这样: bonus_left | bonus_spent 20 15 我知道我可以复制表并用where子句连接它们,但有没有办法在单个查询上执行此操

我有一项任务,我一直忙得不可开交

所以我有一个表
transactions
,它有两列
bonus
type
,比如:

bonus | type      
20       1
15      -1
我想要的是将一个带有
bonus
列的查询按
type
分为两列
bonus\u-spend
bonus\u-left

它应该看起来像这样:

bonus_left | bonus_spent
    20            15

我知道我可以复制表并用where子句连接它们,但有没有办法在单个查询上执行此操作?

在香草SQL中,您将使用条件聚合。我们使用
user\u id
列,该列指示奖金属于谁,我使用
SUM
进行汇总,以允许每种类型的奖金有一种以上:

SELECT user_id,
    SUM(CASE WHEN type =  1 THEN bonus ELSE 0 END) AS bonus_left,
    SUM(CASE WHEN type = -1 THEN bonus ELSE 0 END) AS bonus_spent
FROM transactions
GROUP BY user_id
输出:

user_id     bonus_left  bonus_spent
1           20          15
我同意你的看法,你应该记下正确的答案。对于完整性和一些Knex:

knex('users AS u')
  .join('transactions AS t', 'u.id', 't.user_id')
  .select('u.id', 'u.name')
  .sum(knex.raw('CASE WHEN t.type = 1 THEN t.bonus ELSE 0 END AS bonus_left'))
  .sum(knex.raw('CASE WHEN t.type = -1 THEN t.bonus ELSE 0 END AS bonus_spent'))
注意,由于缺少表模式,这是未经测试的。不过看起来大概是这样。您也可以将两个
SUM
s作为
knex.raw
嵌入选择列表中,但这可能更有组织性

考虑将
类型创建为。这将使您无需记住表中的“幻数”,而无需编写如下比较:

CASE WHEN type = 'bonus_left'
它还可以防止您意外输入其他整数,如
99
,因为Postgres会检查插入


我一直担心,在同一个表中“剩余”奖金与“花费”奖金反映了模式的更广泛问题(例如,为什么奖金总额不是我们需要跟踪的唯一值?)

是否有其他列可以识别奖金指的是谁/什么?是的,有一个字段说它属于用户_idI,我冒昧地删除了
mysql
psql
标记,因为我的记忆是你的目标是Postgres。很好,我没有想到这种方法,但它只有在我需要一个总数的时候才有效?@MereyNurlan没有,如果每个
user\u id
只有一个值,您将只获得该值。您需要使用某种形式的聚合函数,因为您需要通过
user\u id
GROUP进行分组,以将所有值放在一行中。如果您知道每个用户每种类型只有一个奖金,您可以使用
MAX
MIN
而不是
SUM
,因为这样会更有效。在这种情况下,您将从
案例
表达式中删除
ELSE 0
,因为它不是必需的。这是我无法提供的部分。谢谢你填补了这个空白。