在sql join中使用列而不将其添加到group by子句
技术问答
269 人阅读
|
0 人回复
|
2023-09-12
|
我的实际表结构要复杂得多,但以下是两个简化的表定义:/ }! G+ e+ t. G& q( L* I1 L
桌子 invoice6 D7 d8 S' i4 \
CREATE TABLE invoice ( id integer NOT NULL, create_datetime timestamp with time zone NOT NULL, total numeric(22,10) NOT NULL);id create_datetime total ----------------------------100 2014-05- 桌子 payment_invoice
& s+ H3 U$ j! v! l/ kCREATE TABLE payment_invoice ( invoice_id integer, amount numeric(22,10));invoice_id amount-------------------100 15000 1500我想通过连接上述2个表来选择数据,并且所选数据应如下所示:-, Q- W8 w, |1 R
month total_invoice_count outstanding_balance5005/2014 50550055500555055500我正在使用的查询:( G) E( C3 F1 w$ j* i1 g
selectto_char(date_trunc('month',i.create_datetime),'MM/YYYY') as month,count(i.id) as total_invoice_count,(sum(i.total) - sum(pi.amount)) as outstanding_balancefrom invoice ijoin payment_invoice pi on i.id=pi.invoice_idgroup by date_trunc('month',i.create_datetime)order by date_trunc('month',i.create_datetime);上面的查询给了我错误的结果sum(i.total) - sum(pi.amount)回报(1000 1000 1000-(100 200/ I1 r: @: s" R i, n5 v. L8 j
150)= 2550 。( T/ B# Z" W+ _5 k1 |
我希望它能回来(1000)-(100 200 150= 550( B6 } z- U# ]4 S: R) t
而且,我不能把它它i.total - sum(pi.amount),因此,我被迫将军i.total列添加到group by我不想这样做。
9 ?% c6 s* O y" m
3 @1 Z: _8 d4 M: ], Y 解决方案: # w' F! a9 L) e( f% e
每张发票只需要一行,所以payment_invoice请先汇总-加入前最好。
+ K, Z2 \. s! [ f选择整个表格后,通常先汇总再汇总_进行合并 最快的方法是:
3 {9 I/ ^' F( e2 z: U' g" c) MSELECT to_char(date_trunc('month',i.create_datetime),'MM/YYYY') AS month count(*) AS total_invoice_count (sum(i.total) - COALESCE(sum(pi.paid),0)) AS outstanding_balanceFROM invoice iLEFT JOIN ( SELECT invoice_id AS id,sum(amount) AS paid FROM payment_invoice pi GROUP BY 1 ) pi USING (id)GROUP BY date_trunc('month',i.create_datetime)ORDER BY date_trunc('month',i.create_datetime);LEFT JOIN1 Z$ t q1 n. N# i; ?
这里很重要。你不想失去它。payment_invoice其中没有相应的发票,这将存在Plain上发生JOIN。
3 v, d& O; i. O% v9 q相应地,把它拿走COALESCE()用于支付总和,总和可能是NULL。% J- r! \( I) @
SQL Fiddle 测试用例改进。 |
|
|
|
|
|