我有一个任务要弄清楚。
所以我有这个表transactions
,它有2列bonus
和type
,如:
bonus | type
20 1
15 -1
我想要的是一个查询,其中bonus
列被bonus_spent
分为两列bonus_left
和type
。
它应该看起来像这样:
bonus_left | bonus_spent
20 15
我知道我可以复制表并将它们与where子句连接在一起,但是有什么方法可以对单个查询执行此操作?
答案 0 :(得分:2)
在普通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
答案 1 :(得分:2)
我同意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'))
请注意,由于缺少表架构,因此未经测试。看起来大概像这样。您也可以将两个SUM
作为knex.raw
嵌入到选择列表中,但这可能更有条理。
请考虑将type
创建为Postgres enum。这样一来,您不必记住表中的“魔术数字”,而可以编写如下比较:
CASE WHEN type = 'bonus_left'
这还可以防止您意外输入其他整数,例如99
,因为Postgres将对插入进行类型检查。
我担心的是,同一张表中的奖金“左”与“花”反映了架构的一个更广泛的问题(例如,为什么总奖金不仍然是我们需要跟踪的唯一值) ?),但那可能只是我的妄想症!