Received: from localhost (maia-3.hub.org [200.46.204.184]) by postgresql.org (Postfix) with ESMTP id 9139C9FA311 for ; Wed, 13 Dec 2006 06:29:26 -0400 (AST) Received: from postgresql.org ([200.46.204.71]) by localhost (mx1.hub.org [200.46.204.184]) (amavisd-new, port 10024) with ESMTP id 28355-09 for ; Wed, 13 Dec 2006 06:29:18 -0400 (AST) X-Greylist: from auto-whitelisted by SQLgrey-1.7.4 Received: from mx3.ipf.is (man.ipf.is [85.197.192.163]) by postgresql.org (Postfix) with ESMTP id EB6869FA1DA for ; Wed, 13 Dec 2006 06:29:21 -0400 (AST) Received: (qmail 26674 invoked by uid 1010); 13 Dec 2006 10:22:51 +0000 Received: from 88.149.106.19 by man (envelope-from , uid 1008) with qmail-scanner-1.25-st-qms (clamdscan: 0.88.4/1639. spamassassin: 3.1.4. perlscan: 1.25-st-qms. Clear:RC:1(88.149.106.19):SA:0(-2.5/4.5):. Processed in 2.63307 secs); 13 Dec 2006 10:22:51 -0000 X-Antivirus-HIVE-Mail-From: gnari@hive.is via man X-Antivirus-HIVE: 1.25-st-qms (Clear:RC:1(88.149.106.19):SA:0(-2.5/4.5):. Processed in 2.63307 secs Process 26655) Received: from dsl-149-106-19.hive.is (HELO ?192.168.1.33?) (88.149.106.19) by mx3.ipf.is with SMTP; 13 Dec 2006 10:22:48 +0000 Subject: Re: join and sort on 'best match' From: Ragnar To: Dirk Griffioen Cc: pgsql-sql@postgresql.org In-Reply-To: <457FC751.6080104@code-shop.com> References: <457FC751.6080104@code-shop.com> Content-Type: text/plain; charset=ISO-8859-1 Date: Wed, 13 Dec 2006 10:29:47 +0000 Message-Id: <1166005787.6369.79.camel@localhost.localdomain> Mime-Version: 1.0 X-Mailer: Evolution 2.8.1 Content-Transfer-Encoding: 8bit X-Virus-Scanned: Maia Mailguard 1.0.1 X-Archive-Number: 200612/101 X-Sequence-Number: 27057 On miš, 2006-12-13 at 10:26 +0100, Dirk Griffioen wrote: > I have been breaking my head on the following problem: how to join 2 > tables and sort the results on the best match. ^^^^^^^^^^^^^ > - there are 3 tables, items, tags and items_tags. The items_tags table > links items to tags. > - I have one item which has certain tags, and I want to look up all > the other items that have those tags as well looks to me like you want to join: items->item_tags->tags->item_tags->items so the basic select is: SELECT * FROM items AS i1 JOIN items_tags AS it1 ON (it1.item_id = i1.id) JOIN tags AS t ON (t.tag_id = it1.tag_id) JOIN items_tags AS it2 ON (it2.tag_id = t.tag_id) JOIN items AS i2 ON (i2.id = it2.item_id) WHERE i1.id=? > - results should be sorted and presented by 'best match': first all > the items that have 3 tags in common, then 2 and last 1 this would be: SELECT i1.id,i2.id,COUNT(*) as quantity FROM items AS i1 JOIN items_tags AS it1 ON (it1.item_id = i1.id) JOIN tags AS t ON (t.tag_id = it1.tag_id) JOIN items_tags AS it2 ON (it2.tag_id = t.tag_id) JOIN items AS i2 ON (i2.id = it2.item_id) WHERE i1.id=? GROUP by i1.id,i2.id ORDER BY quantity DESC > I thought I had found the solution (my test cases worked), but I now > find cases that should be found by the query but are not. if this does not work, please provide us with a counter example. gnari