Thread: A subselect in an aggregate
This statement works: select date, (select sum(qty * price) from orderdetail d where d.orderid = orders.orderid) from orders But when I try to do something like this: select date, sum(select sum(qty * price) from orderdetail d where d.orderid = orders.orderid) from orders group by date I get ERROR: parser: parse error at or near "select" Is there a way to apply an agregate function to a subselect like this?
Bryan White wrote: > > This statement works: > select date, (select sum(qty * price) from orderdetail d where d.orderid = > orders.orderid) from orders > > But when I try to do something like this: > > select date, sum(select sum(qty * price) from orderdetail d where d.orderid > = orders.orderid) from orders group by date > > I get ERROR: parser: parse error at or near "select" > > Is there a way to apply an agregate function to a subselect like this? Avoiding the question, I'm wondering if this simpler form wouldn't be what you're after? select o.date, sum(d.qty * d.price) from orderdetail d, orders owhere d.orderid = o.orderidgroup by o.date Regards, Ed Loehr
> Bryan White wrote: > > > > This statement works: > > select date, (select sum(qty * price) from orderdetail d where d.orderid = > > orders.orderid) from orders > > > > But when I try to do something like this: > > > > select date, sum(select sum(qty * price) from orderdetail d where d.orderid > > = orders.orderid) from orders group by date > > > > I get ERROR: parser: parse error at or near "select" > > > > Is there a way to apply an agregate function to a subselect like this? > > Avoiding the question, I'm wondering if this simpler form wouldn't be > what you're after? > > select o.date, sum(d.qty * d.price) > from orderdetail d, orders o > where d.orderid = o.orderid > group by o.date This is very slow (acutally I killed it after about 5 minutes): select o.date,sum(d.qty * d.price) from orderdetail d,orders o where o.date = '6/1/2000' group by o.date; Explained: Aggregate (cost=0.00..41074641.24 rows=120300337 width=20) -> Group (cost=0.00..38067132.80 rows=1203003374 width=20) -> Nested Loop (cost=0.00..35059624.37 rows=1203003374 width=20) -> Index Scan using iorddate3on orders o (cost=0.00..6917.34 rows=1808 width=4) -> Seq Scan on orderdetail d (cost=0.00..12733.78 rows=665378 width=16) Doing a squential scan of orderdetail inside a loop seems to be what kills it. This is quick (it takes a couple of seconds): select o.date,(select sum(od.qty * od.price) from orderdetail od where od.orderid = o.orderid) from orders o where o.date = '6/1/2000'; Explained: Index Scan using iorddate3 on orders o (cost=0.00..6917.34 rows=1808 width=8) SubPlan -> Aggregate (cost=45.24..45.24 rows=1 width=16) -> Index Scan using iodid on orderdetail od (cost=0.00..45.21 rows=11 width=16) I suppose I can do my own grouping on the result data but I would like to avoid that if I could. Which brings me back to the original question: Is there a way to apply an aggregate function to a subselect?
"Bryan White" <bryan@arcamax.com> writes: > This is very slow (acutally I killed it after about 5 minutes): > select o.date,sum(d.qty * d.price) from orderdetail d,orders o where o.date > = '6/1/2000' group by o.date; > This is quick (it takes a couple of seconds): > select o.date,(select sum(od.qty * od.price) from orderdetail od where > od.orderid = o.orderid) from orders o where o.date = '6/1/2000'; Well, they're not computing the same thing, are they? Since there's no constraint on d.orderid in the first example, you're asking for the sum over ALL orderdetail records ... repeated over again for each order record. For equivalent constraints, I'd expect the first form to be at least as fast as the second, probably faster. > Which brings me back to the original question: Is > there a way to apply an aggregate function to a subselect? Sure --- you just forgot that a sub-select expression requires its very own parentheses, so you need two sets:sum((select ....)) But the other way is probably better... regards, tom lane