[英]Laravel, MYSQL full join workaround on two aggregated tables
I've got a table called transactions
with below schema:我有一个名为
transactions
的表,其架构如下:
TRANSACTIONS
+----+-----------------+-------------------+--------+
| id | to (account_id) | from (account_id) | amount |
+----+-----------------+-------------------+--------+
| 1 | 1 | 3 | 500 |
+----+-----------------+-------------------+--------+
| 2 | 2 | 1 | 250 |
+----+-----------------+-------------------+--------+
| 3 | 1 | 2 | 100 |
+----+-----------------+-------------------+--------+
| 4 | 4 | 2 | 50 |
+----+-----------------+-------------------+--------+
to
and from
are foreign keys to id
on table accounts
. to
和from
是表accounts
上id
外键。
I wanna get the subtraction
of sum
of all received transactions
from all paid transactions
of selected accounts
as in the example accounts 1
and 2
and all the accounts which whom those had transaction with
.我想从
selected accounts
all paid transactions
中subtraction
all received transactions
sum
,如示例账户1
和2
以及all the accounts which whom those had transaction with
.
This is the desired result:这是想要的结果:
DESIRED QUERY RESULT
+---+------------+---------------+-----------+---------+
| # | account_id | totalReceived | totalPaid | balance |
+---+------------+---------------+-----------+---------+
| 1 | 1 | 600 | 250 | 350 |
+---+------------+---------------+-----------+---------+
| 2 | 2 | 250 | 150 | 100 |
+---+------------+---------------+-----------+---------+
| 3 | 3 | 0 | 500 | -500 |
+---+------------+---------------+-----------+---------+
| 4 | 4 | 50 | 0 | 50 |
+---+------------+---------------+-----------+---------+
What I've got so far:到目前为止我所得到的:
as I'm using Laravel with query builder I run it like follows:当我将 Laravel 与查询构建器一起使用时,我按如下方式运行它:
$k = [1, 2];
$receivedTransactions = DB::table('transactions as t1')->selectRaw('t1.to as account_id, sum(t1.amount) as totalReceived')
->whereIn('t1.from', $k)->orWhereIn('t1.to', $k)->groupBy('t1.to');
$paidTransactions = DB::table('transactions as t2')->selectRaw('t2.from as account_id, sum(t2.amount) as totalPaid')
->whereIn('t2.from', $k)->orWhereIn('t2.to', $k)->groupBy('t2.from');
$result = $receivedTransactions->leftJoinSub($paidTransactions, 't2', function ($join) {
$join->on('t1.to', 't2.account_id');
})->selectRaw('totalPaid, (COALESCE(sum(t1.amount),0) - COALESCE(totalPaid,0)) as balance');
The big problem is it doesn't give me the 3rd row in the desired result table, because I don't have full join and I don't get the result from the right table which doesn't have corresponding row in the join so null
.最大的问题是它没有给我所需结果表中的第 3 行,因为我没有完全连接,而且我没有从正确的表中获得结果,该表在连接中没有相应的行,所以
null
。
this is what I get:这就是我得到的:
CURRENT QUERY RESULT
+---+------------+---------------+-----------+---------+
| # | account_id | totalReceived | totalPaid | balance |
+---+------------+---------------+-----------+---------+
| 1 | 1 | 600 | 250 | 350 |
+---+------------+---------------+-----------+---------+
| 2 | 2 | 250 | 150 | 100 |
+---+------------+---------------+-----------+---------+
| 4 | 4 | 50 | 0 | 50 |
+---+------------+---------------+-----------+---------+
I don't get the account_id 3
which was involved in giving account 1
the transaction no.1我没有得到 account_id
3
参与给账户1
的交易 1
Any help would be really appreciated.任何帮助将非常感激。 It doesn't matter if it is in Raw MYSQL format or laravel query builder.
它是原始 MYSQL 格式还是 laravel 查询构建器都没有关系。 Thank you very much.
非常感谢。
I did this directly on mysql and after I tried to translate to Laravel syntax我直接在 mysql 上做了这个,在我尝试翻译成 Laravel 语法之后
SELECT
DISTINCT base_accounts.account_id,
COALESCE(t1.totalReceived, 0) as totalReceived,
COALESCE(t2.totalPaid, 0) AS totalPaid,
COALESCE(t1.totalReceived, 0) - COALESCE(t2.totalPaid, 0) as totalBalance
FROM (
SELECT `to` as account_id FROM transactions UNION SELECT `from` FROM transactions
) as base_accounts
LEFT JOIN (
SELECT `to` as account_id, sum(amount) as totalReceived FROM transactions GROUP BY `to`
) as t1 on base_accounts.account_id = t1.account_id
LEFT JOIN (
SELECT `from` as account_id, sum(amount) as totalPaid FROM transactions GROUP BY `from`
) as t2 on base_accounts.account_id = t2.account_id
ORDER BY base_accounts.account_id
\DB::table(\DB::raw('(SELECT `to` as account_id FROM transactions UNION SELECT `from` FROM transactions) as base_accounts'))
->select(DB::raw('
DISTINCT base_accounts.account_id,
COALESCE(t1.totalReceived, 0) as totalReceived,
COALESCE(t2.totalPaid, 0) AS totalPaid,
COALESCE(t1.totalReceived, 0) - COALESCE(t2.totalPaid, 0) as totalBalance
'))
->leftJoin(
\DB::raw('(SELECT `to` as account_id, sum(amount) as totalReceived FROM transactions GROUP BY `to`) as t1'),
'base_accounts.account_id',
'=',
't1.account_id'
)
->leftJoin(
\DB::raw('(SELECT `from` as account_id, sum(amount) as totalPaid FROM transactions GROUP BY `from`) as t2'),
'base_accounts.account_id',
'=',
't2.account_id'
)->orderBy('base_accounts.account_id')->get();
I tested the query and worked fine.我测试了查询并且工作正常。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.