我有两个表,一个是交易,另一个是费用
交易表:
id amount created
1 300 2019-10-01 00:00:00
2 200 2019-11-01 00:00:00
3 230 2019-11-13 00:00:00
4 130 2019-11-13 00:00:00
费用表:
id amount created
1 600 2019-11-13 00:00:00
两个表的总和,我在下面写了对我来说很好的查询。
(SELECT IFNULL(date(t1.created), date(ex.created)) as Date , sum(t1.amount) as ReceiveAmount,ex.amount as ExpensesAmount
FROM transactions as t1
LEFT JOIN (
SELECT sum(e.amount) as amount, created
FROM expenses as e
group by date(e.created)
) as ex
ON date(ex.created) = date(t1.created)
GROUP BY date(t1.created))
UNION
(SELECT IFNULL(date(t1.created), date(ex.created)) as Date, sum(t1.amount) as Receive,ex.amount as ExpensesAmount
FROM transactions as t1
RIGHT JOIN (
SELECT sum(e.amount) as amount, created
FROM expenses as e
group by date(e.created)
) as ex
ON date(t1.created) = date(ex.created)
GROUP BY date(t1.created)) ORDER BY Date
输出:
Date ReceiveAmount ExpensesAmount
2019-10-01 300 NULL
2019-11-01 200 NULL
2019-11-13 360 600
但是现在,如果我想从两个表中获取所有金额而不求和。我缺少日期2019-11-13
的一笔交易。
(SELECT IFNULL(date(t1.created), date(ex.created)) as Date , t1.amount as ReceiveAmount,ex.amount as ExpensesAmount
FROM transactions as t1
LEFT JOIN (
SELECT e.amount as amount, created
FROM expenses as e
group by date(e.created)
) as ex
ON date(ex.created) = date(t1.created)
GROUP BY date(t1.created))
UNION
(SELECT IFNULL(date(t1.created), date(ex.created)) as Date, t1.amount as Receive,ex.amount as ExpensesAmount
FROM transactions as t1
RIGHT JOIN (
SELECT e.amount as amount, created
FROM expenses as e
group by date(e.created)
) as ex
ON date(t1.created) = date(ex.created)
GROUP BY date(t1.created)) ORDER BY Date
输出:
2019-10-01 300 NULL
2019-11-01 200 NULL
2019-11-13 230 600
在日期2019-11-13
缺少一笔交易。
预期结果:
2019-10-01 300 NULL
2019-11-01 200 NULL
2019-11-13 230 600
2019-11-13 130 NULL
在这里,我怎么能得到我想要的结果?
答案 0 :(得分:2)
如果运行的是MySQL 8.0,则可以将row_number()
分配给每个具有created
分区的表的记录,然后创建left join
:
select t.created, t.amount, e.amount
from (
select
t.*,
row_number() over(partition by created order by id) rn
from transactions t
) t
left join (
select
e.*,
row_number() over(partition by created order by id) rn
from expenses e
) e
on e.created = t.created and e.rn = t.rn
如果两个表中的任何一个表中的日期都可能不存在于另一个表中,则它会有些复杂。基本上,我们需要模拟MySQL中不存在的full join
。这是使用union all
的一种方法:
select created, max(t_amount) t_amount, max(e_amount) e_amount
from (
select
created,
amount t_amount,
null e_amount,
row_number() over(partition by created order by id) rn
from transactions
union all
select
created,
null,
amount,
row_number() over(partition by created order by id)
from expenses
) d
group by created, rn
答案 1 :(得分:0)
如果您不想求和,就不应该分组。其他rdbms会对此引发错误。 不进行分组,您应该获得所有记录。
但是我想您不会得到理想的结果,因为这些练习将在2019-11-13并入这两项交易中