Thread: UNION and rows improperly unified: query optimization question
Greetings. I have an accounting system in Postgres which has tables 'transact' and 'gl_entry'. Each check, deposit, etc has one entry in transact, but there may be multiple entries in gl_entry if one check was for multiple expenses that are tracked separately (for example, one check to AT&T might cover both telephone and Internet service, which are two different costing categories). Also, debit and credit are supposed to appear in seperate columns, even though they are one number with either positive or negative sign in the table. So I run two select and combine them using a union statement, but this improperly combines two gl_entry lines that do not differ in amount or transaction ID. My solution is to select also the unique ide number from gl_entry and remove it by wrapping the SELECT...UNION...SELECT in another SELECT. This seems awfully ugly. Is there a better way? Here is the query that I use now, which produces correct results: SELECT postdate, person, debit, credit, descr, num FROM ( SELECT t.postdate, t.person, abs(g.amt) AS debit, '0.00' AScredit, t.descr, t.num, g.id AS gid FROM transact t, gl_entry g ' + WHERE t.id = g.transact_id AND g.amt >= 0UNION SELECT t.postdate, t.person, '0.00' AS debit, abs(g.amt) AS credit, t.descr, t.num, g.id AS gid FROM transactt, gl_entry g WHERE t.id = g.transact_id AND g.amt < 0 ) AS subselect ORDER BY postdate I would like to get rid of the outer SELECT, if possible. -- Henry House The attached file is a digital signature. See <http://romana.hajhouse.org/pgp> for information. My OpenPGP key: <http://romana.hajhouse.org/hajhouse.asc>.
Henry House <hajhouse@houseag.com> writes: > So I run two select and combine them > using a union statement, but this improperly combines two gl_entry lines th= > at > do not differ in amount or transaction ID. AFAICT you do not want duplicate-row elimination at all. Why don't you use UNION ALL? regards, tom lane
Henry, How about: SELECT t.postdate, t.person, case where g.amt >= 0 then g.amt else '0.00' end as debit, case where g.amt < 0 then '0.00'else -g.amt end as credit, t.descr, t.num FROM transact t, gl_entry g ORDER BY postdate; Henry House wrote: [...] > SELECT postdate, person, debit, credit, descr, num FROM ( > SELECT t.postdate, t.person, abs(g.amt) AS debit, '0.00' AS credit, t.descr, t.num, g.id AS gid > FROM transact t, gl_entry g ' + > WHERE t.id = g.transact_id AND g.amt >= 0 > UNION > SELECT t.postdate, t.person, '0.00' AS debit, abs(g.amt) AS credit, t.descr, t.num, g.id AS gid > FROM transact t, gl_entry g > WHERE t.id = g.transact_id AND g.amt < 0 > ) AS subselect ORDER BY postdate > > I would like to get rid of the outer SELECT, if possible. > > -- > Henry House > The attached file is a digital signature. See <http://romana.hajhouse.org/pgp> > for information. My OpenPGP key: <http://romana.hajhouse.org/hajhouse.asc>. > > ------------------------------------------------------------------------ > Part 1.2Type: application/pgp-signature
"Henry House" <hajhouse@houseag.com> wrote in message news:20020211200524.GA17170@wotan... > Greetings. I have an accounting system in Postgres which has tables > 'transact' and 'gl_entry'. Each check, deposit, etc has one entry in > transact, but there may be multiple entries in gl_entry if one check was for > multiple expenses that are tracked separately (for example, one check to AT= > &T > might cover both telephone and Internet service, which are two different > costing categories). Also, debit and credit are supposed to appear in > seperate columns, even though they are one number with either positive or > negative sign in the table. So I run two select and combine them > using a union statement, but this improperly combines two gl_entry lines th= > at > do not differ in amount or transaction ID. My solution is to select also the > unique ide number from gl_entry and remove it by wrapping the > SELECT...UNION...SELECT in another SELECT. This seems awfully ugly. Is there > a better way? The result of a SELECT statement is a set of values, in the mathematical sense of the word "set". Sets do not have duplicate values, so here the database is behaving correctly. That is what UNION means, in SQL, and in any math textbook. What's wrong with just the inner select? Why do you have to get rid of the unique id? It's not hurting anything; it's helping in fact. Marshall