| payments | | transactions | | transaction_items |
|:--------------:| |:------------:| |:-----------------:|
| id | | id | | id |
| date | | number | | transaction_id |
| amount | | date | | description |
| transaction_id | | val | | price |
| discount |
| quantity |
Run Code Online (Sandbox Code Playgroud)
我正在尝试显示交易付款列表,并在每次付款后显示当前余额。以下是预期结果的示例
| number | DATE(p.date) | total | paid | balance |
| 1355 | 2016-10-31 | 899.00 | 450.00 | 449.00 |
| 1355 | 2016-12-06 | 899.00 | 449.00 | 0.00 |
| 1359 | 2016-09-28 | 4045.00 | 1515.00 | 2530 |
| 1359 | 2016-10-24 | 4045.00 | 35.00 | 2495.00 |
| 1361 | 2016-09-28 | 1548.00 | 1548.00 | 0.00 |
Run Code Online (Sandbox Code Playgroud)
到目前为止,这是我的查询,但 where 子句中有错误
select
t.number,
DATE(p.date),
ti.total 'total',
SUM(p.amount) 'paid',
ti.total - paid.total 'balance'
from payments p
left join transactions t
on p.transaction_id = t.id
left join (
select inner_ti.transaction_id, sum((inner_ti.price - inner_ti.discount) * inner_ti.quantity) 'total'
from transaction_items inner_ti
group by inner_ti.transaction_id
) ti on t.id = ti.transaction_id
left join (
select inner_p.transaction_id, sum(inner_p.amount) 'total'
from payments inner_p
where inner_p.date <= p.date -- error unknown column p.date
group by inner_p.transaction_id
) paid on t.id = paid.transaction_id
group by t.number, DATE(p.date), ti.total, paid.total
order by DATE(p.date) ASC
Run Code Online (Sandbox Code Playgroud)
请注意,我正在分组,p.date
因为我们关注的是当天支付的总金额。
有人可以启发我为什么我会收到那个错误吗?是否有任何解决方法可以达到预期的结果?
McN*_*ets 12
查询中的两个嵌套选择称为派生表。派生表并不意味着与参与查询的其他数据集相关,因此不允许在嵌套查询中对它们进行外部引用。
解决该问题的一种方法是重写您的查询,以便将有问题的选择移动到允许关联的上下文中。在您的情况下,您可以将有问题的子查询移动到 SELECT 子句:
select t.number,
DATE(p.date),
ti.total 'total',
SUM(p.amount) 'paid',
ti.total - (select sum(inner_p.amount)
from payments inner_p
where inner_p.transaction_id = p.transaction_id
and inner_p.date <= p.date
) 'balance'
from payments p
left join transactions t
on p.transaction_id = t.id
left join (
select inner_ti.transaction_id,
sum((inner_ti.price - inner_ti.discount) * inner_ti.quantity) 'total'
from transaction_items inner_ti
group by inner_ti.transaction_id
) ti
on t.id = ti.transaction_id
group by t.number, DATE(p.date), ti.total, 'balance'
order by DATE(p.date) ASC;
Run Code Online (Sandbox Code Playgroud)
rextester这里
为完整起见,SQL 标准实际上具有允许关联派生表的语法。它被称为横向连接。从语法的角度来看,它看起来几乎和普通的 join 完全一样,你只需要在 之后添加LATERAL
关键字JOIN
:
…
left join lateral (
select inner_p.transaction_id, sum(inner_p.amount) 'total'
from payments inner_p
where inner_p.date <= p.date -- this outer reference would be valid
group by inner_p.transaction_id
) paid on t.id = paid.transaction_id
…
Run Code Online (Sandbox Code Playgroud)
添加的关键字使一切变得不同,因为只有使用该关键字,嵌套查询才允许引用同一 FROM 子句中的其他数据集(在最近的 JOIN 关键字的左侧)。
PostgreSQL 和 Oracle 目前支持横向连接。SQL Server 也支持语法略有不同(且不太灵活)的类似概念。您可能已经猜到了,MySQL 目前不支持任何此类内容。
归档时间: |
|
查看次数: |
22224 次 |
最近记录: |