如何根据knex.js中的第三列将一列拆分为两列?
How to split one column into two separated by according to third column in knex.js?
我有一个任务一直在绞尽脑汁。
所以我有这个 table transactions
它有 2 列 bonus
和 type
像 :
bonus | type
20 1
15 -1
我想要的是 bonus
列的查询按 type
.
分为两列 bonus_spent
和 bonus_left
大概应该是这样的:
bonus_left | bonus_spent
20 15
我知道我可以复制 tables 并用 where 子句连接它们,但是有什么方法可以对单个查询执行此操作吗?
在原版 SQL 中,您将使用条件聚合。我们使用 user_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
我同意 Nick,恕我直言,您应该将答案标记为正确。为了完整性和一些 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'))
请注意,缺少您的 table 架构,这是未经测试的。它看起来大致像这样。您也可以将两个 SUM
作为 knex.raw
嵌入 select 列表中,但这可能更有条理。
考虑将 type
创建为 Postgres enum。这将使您不必记住 table 中的 'magic number' 是什么,而是像这样编写比较:
CASE WHEN type = 'bonus_left'
它还可以防止您意外输入一些其他整数,例如 99
,因为 Postgres 将对插入进行类型检查。
我一直担心在同一个 table 中有奖金 'left' 与 'spent' 反映了架构的更广泛问题(例如,为什么不是总金额奖金仍然是我们需要跟踪的唯一价值?)但也许这只是我的偏执狂!
我有一个任务一直在绞尽脑汁。
所以我有这个 table transactions
它有 2 列 bonus
和 type
像 :
bonus | type
20 1
15 -1
我想要的是 bonus
列的查询按 type
.
bonus_spent
和 bonus_left
大概应该是这样的:
bonus_left | bonus_spent
20 15
我知道我可以复制 tables 并用 where 子句连接它们,但是有什么方法可以对单个查询执行此操作吗?
在原版 SQL 中,您将使用条件聚合。我们使用 user_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
我同意 Nick,恕我直言,您应该将答案标记为正确。为了完整性和一些 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'))
请注意,缺少您的 table 架构,这是未经测试的。它看起来大致像这样。您也可以将两个 SUM
作为 knex.raw
嵌入 select 列表中,但这可能更有条理。
考虑将 type
创建为 Postgres enum。这将使您不必记住 table 中的 'magic number' 是什么,而是像这样编写比较:
CASE WHEN type = 'bonus_left'
它还可以防止您意外输入一些其他整数,例如 99
,因为 Postgres 将对插入进行类型检查。
我一直担心在同一个 table 中有奖金 'left' 与 'spent' 反映了架构的更广泛问题(例如,为什么不是总金额奖金仍然是我们需要跟踪的唯一价值?)但也许这只是我的偏执狂!