Received: from makus.postgresql.org (makus.postgresql.org [98.129.198.125]) by mail.postgresql.org (Postfix) with ESMTP id 035DC7661B8 for ; Thu, 21 Jun 2012 15:41:25 -0300 (ADT) Received: from smtp106.prem.mail.ac4.yahoo.com ([76.13.13.45]) by makus.postgresql.org with smtp (Exim 4.72) (envelope-from ) id 1ShmJn-0001Ie-Dh for pgsql-sql@postgresql.org; Thu, 21 Jun 2012 18:41:24 +0000 Received: (qmail 46362 invoked from network); 21 Jun 2012 18:41:10 -0000 DomainKey-Signature: a=rsa-sha1; q=dns; c=nofws; s=s1024; d=yahoo.com; h=DKIM-Signature:X-Yahoo-Newman-Property:X-YMail-OSG:X-Yahoo-SMTP:Received:From:To:References:In-Reply-To:Subject:Date:Message-ID:MIME-Version:Content-Type:Content-Transfer-Encoding:X-Mailer:Thread-Index:Content-Language; b=oDkq+8+NXOTAMgjX4Tk4jJt2FKe9eimp+QWUHIKXr6DEFhaqSZophwd4NGFRYvZi78WVca384ovYj+LcLHX3GpyZHyNRmJqOMFCHsyluvp0VmS6Z3cIGdJ9JAG2NhFOLSzaNP00SFTRU8bA+vc0u8Q1Om54jijH0lfKAhg9iDuo= ; DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s1024; t=1340304069; bh=TlxmjLXKgQoRapM5Drh4nIRepMjHWHWz6ygD4VicXU8=; h=X-Yahoo-Newman-Property:X-YMail-OSG:X-Yahoo-SMTP:Received:From:To:References:In-Reply-To:Subject:Date:Message-ID:MIME-Version:Content-Type:Content-Transfer-Encoding:X-Mailer:Thread-Index:Content-Language; b=OtV/D10yhFvMSSZr8FbByukRKbTvJy0cj//ueIVrKvOFE0Dzy1/+J1MOEO3/g8EtElIFIsiWbLs6kmoaU5p3cIiMd6Rc2ySRqg+ts9JGN4t3ZeuFZxlrm5H5ozLmTmELLpx7AIIJlqlKvSLZg6wiFSqgQdd2i719eKMgKb9M8OA= X-Yahoo-Newman-Property: ymail-3 X-YMail-OSG: 6iesoIMVM1lZVkz9NiNb09ashD.tFc4gZJPnKMRcZSVGDjN 9KR1zwCqXZL.LCWwirscbtxtUU0CQfBrfPALH2Y5yiu0gTAGvc10v.0sBqaO yWMtJrdOjtLjNu7YJJR62prRbPthmx81XHUkFIA4Lw7WEpq81jRxHXwcCRZn lLSLstQkBW4fK3Rjf88QaN8OBaCWl6W8kNPxssd4xmb82BldjH4ZCJQwlve. DHVZghwIl4A.Dz8Tm6iKh3gl9ezzZqjDciNP2Jxit7qzf6OpBwZD.4FG0sOG _A_.y4GVHqJ6iPiGc5lOODdfVNRyf190VTLWvG404ki3QyzyjviApxFV1bGI wX4ulTBoBObite8vCigDKkuCEueWC9K0cW76hGFwVr9GD58uLXf_UepQeY_m 28P9L9O.Bc7Qizykyz8kJ X-Yahoo-SMTP: mpGJl6eswBD2IBufoVEg0Pa8gg-- Received: from WolfDog (polobo@24.93.23.188 with login) by smtp106.prem.mail.ac4.yahoo.com with SMTP; 21 Jun 2012 11:41:09 -0700 PDT From: "David Johnston" To: "'Rihad'" , References: <4FE35E88.6010805@stream.az> In-Reply-To: <4FE35E88.6010805@stream.az> Subject: Re: Need help building this query Date: Thu, 21 Jun 2012 14:40:35 -0400 Message-ID: <00e401cd4fdd$589b1e60$09d15b20$@yahoo.com> MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit X-Mailer: Microsoft Outlook 14.0 Thread-Index: AQGGJa/0jjMlRrhRBv8FikGeWEixUpeTbINQ Content-Language: en-us X-Pg-Spam-Score: -1.9 (-) X-Archive-Number: 201206/65 X-Sequence-Number: 36719 > -----Original Message----- > From: pgsql-sql-owner@postgresql.org [mailto:pgsql-sql- > owner@postgresql.org] On Behalf Of Rihad > Sent: Thursday, June 21, 2012 1:49 PM > To: pgsql-sql@postgresql.org > Subject: [SQL] Need help building this query > > Hi, folks. I currently need to join two tables that lack primary keys, and > columns used to distinguish each record can be duplicated. I need to build > statistics over the data in those tables. Consider this: > > > TableA: > row 1: foo: 123, bar: 456, baz: 789, amount: 10.99, date_of_op: date row 2: > foo: 123, bar: 456, baz: 789, amount: 10.99, date_of_op: date row 3: foo: 123, > bar: 456, baz: 789, amount: 10.99, date_of_op: date > > TableB: > row 1: foo: 123, bar: 456, baz: 789, amount: 10.99, date_of_op: date > > > Columns foo + bar + baz are used to distinguish a performed "operation": > TableA.date_of_op isn't, because it can lag behind TableB. > > Not all different "operations" are in table B. > Table B is just there so we know which "operations" are complete, so to > speak (happening under external means and not under any of my control). > > Now, for each operation (foo+bar+baz) in table A, only *one* row should be > matched in table B, because it only has one matching row there. > The other two in TableA should be considered unmatched. > > Now the query should be able to get count(*) and sum(amount) every day > for that day, considering that matched and unmatched operations should be > counted separately. The report would look something like this: > > TableA.date_of_op TableB.date_of_op > 2012-06-21 [empty] [count(*) and sum(amount) > of all data in TableA for this day unmatched in TableB] > 2012-06-21 2012-06-20 [count(*) and sum(amount) of > all data in TableA matched in TableB for the 20-th] > 2012-06-21 2012-06-19 [count(*) and sum(amount) of > all data in TableA matched in TableB for the 19-th] > > > Can this awkward thing be done in pure SQL, or I'd be better off using > programming for this? > > Thanks, I hope I could explain this. > You seem to be describing a straight reconciliation between two tables. My current means of doing this are programmatically but for the simple case pure SQL should be doable. The main thing is that you have to distinguish between "duplicate" records first and then match them up: TableA Keys: AA AA AA AB AB AC TableB Keys: AA AA AB First you use "ROW_NUMBER() OVER (PARTITION BY key)" to assign an integer "sub-id" to every set of possible keys in both tables: TableA-Sub: AA-1 AA-2 AA-3 AB-1 AB-2 AC-1 TableB-Sub: AA-1 AA-2 AB-1 Now, with these newly constructed key+sub-key values in place, you can perform a simple LEFT (or possibly FULL) JOIN between tables A & B. This makes no allowances for any of kind of desired date restriction on the matching nor does it consider the eventual report that you wish to generate. What this gives you is a listing of ALL rows in both tables with matched records joined together into a single (NULL-less) row while unmatched records will have one of the two resultant columns NULLed SELECT tableA.subid_a, tableB.subid_b FROM tableA FULL OUTER JOIN tableB ON (tableA.subid_a = tableB.subid_b) Requires at least version 8.4 David J.