Thread: Tricky SQL (?)

Tricky SQL (?)

From
Peter Eisentraut
Date:
Let's say I have a table of credits with a customer number attached to it
and a table of refunds with a customer number attached to it. Occasionally
I want to go through this list and check if any customers still have
more credits summed up than refunds.

The technically correct choice for a query would be something like

SELECT customer_nr, sum(amount) FROM ( SELECT customer_nr, amount FROM
credits UNION customer_nr, -amount FROM refunds ) GROUP BY customer_nr
HAVING sum(amount)>0;

Unfortunately, this doesn't work because subselects are not allowed in the
target list. The current solution is to read in all credits and refunds
and have the application (some PHP, some Perl) do the summing and
filtering. But this doesn't only seem clumsy but it creates unneccessay
network traffic.

Seemingly, this should be a common problem, like invoices vs. payments,
assets vs. liabilities, etc. Does anyone have suggestions on how to tackle
this? I am open to changes in the table structure, too.

-- 
Peter Eisentraut
PathWay Computing, Inc.



Re: [SQL] Tricky SQL (?)

From
Chris Bitmead
Date:
Use a temporary table.

Peter Eisentraut wrote:
> 
> Let's say I have a table of credits with a customer number attached to it
> and a table of refunds with a customer number attached to it. Occasionally
> I want to go through this list and check if any customers still have
> more credits summed up than refunds.
> 
> The technically correct choice for a query would be something like
> 
> SELECT customer_nr, sum(amount) FROM ( SELECT customer_nr, amount FROM
> credits UNION customer_nr, -amount FROM refunds ) GROUP BY customer_nr
> HAVING sum(amount)>0;
> 
> Unfortunately, this doesn't work because subselects are not allowed in the
> target list. The current solution is to read in all credits and refunds
> and have the application (some PHP, some Perl) do the summing and
> filtering. But this doesn't only seem clumsy but it creates unneccessay
> network traffic.
> 
> Seemingly, this should be a common problem, like invoices vs. payments,
> assets vs. liabilities, etc. Does anyone have suggestions on how to tackle
> this? I am open to changes in the table structure, too.
> 
> --
> Peter Eisentraut
> PathWay Computing, Inc.

-- 
Chris Bitmead
mailto:chris@tech.com.au
http://www.techphoto.org - Photography News, Stuff that Matters


Re: [SQL] Tricky SQL (?)

From
Herouth Maoz
Date:
At 00:04 +0300 on 03/07/1999, Peter Eisentraut wrote:


> Unfortunately, this doesn't work because subselects are not allowed in the
> target list. The current solution is to read in all credits and refunds
> and have the application (some PHP, some Perl) do the summing and
> filtering. But this doesn't only seem clumsy but it creates unneccessay
> network traffic.

It seems that the current solution would be to create a temporary table,
where you dump the results of your internal query, and then do the external
select. Would be more efficient than doing it on the frontend (network
traffic and all).

Version 6.5 has a facility for naming temporary tables so that you don't
have to worry about exclusive names in a multiuser environment. If you are
using a previous version, you should worry about this only if more than one
person uses said query at a time. Otherwise you should use a preexisting
table, and lock it prior to the query, which would mean another user needs
to wait until the first user finishes the query.

All that said, the solution would be [I haven't tested]:

CREATE TEMP TABLE int_qry ( customer_nr int4, amount decimal(2) );

BEGIN;

INSERT INTO int_qry( customer_nr, amount)
SELECT  customer_nr, amount  FROM credits
UNION  customer_nr, -amount  FROM refunds;

SELECT customer_nr, sum(amount)
FROM int_qry
GROUP BY customer_nr
HAVING sum(amount) > 0;

END;

DROP TABLE int_qry;

I inserted the BEGIN and END just to assert that the two operations are in
fact a single operation. Since temporary tables only exist in one session,
there is little danger of multiple queries messing with each other's
results.

Herouth

--
Herouth Maoz, Internet developer.
Open University of Israel - Telem project
http://telem.openu.ac.il/~herutma