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
,因为它不是必需的。这是我无法提供的部分。谢谢你填补了这个空白。