I'm using PostgreSQL 9.2.4.
Question
I have a table with an ID and a second column of some type. Let's call the type X
. I also have a binary function that operates on a pair of X
s and returns a boolean. We'll call this function f
. f
is transitive; i.e., if f(a,b)
and f(b,c)
both return true, then f(a,c)
will as well.
What I want to do is a get a set of IDs for which all pairs the second column give back true for this binary function. How can I accomplish this?
Performance is not a huge concern; this is part of an import process that will only be run about once annually. The database will not be in use otherwise during this import.
(Relatively) Simple Example
I've created a SQL Fiddle to get things started: http://sqlfiddle.com/#!12/57b97/3. I want to collect IDs by the result of the f
function. Keep in mind that in general, f
might be more complicated. This is just an example.
The output I'm looking for with this example SQL Fiddle would be something like the following:
{1,3,6}
{2,4}
For example, say we choose any pair of IDs from a single set. Let's say we pick 1
and 3
. Then SELECT f((SELECT data FROM temp WHERE id = 1), (SELECT data FROM temp WHERE id = 3));
returns true.
5
doesn't show up anywhere because 'green'
is the only string of length 5. It would be fine if I got back duplicates; I can figure out how to clean them up.
Real Situation Details
In reality, my "second column" is a PostGIS GEOMETRY(LINESTRING)
and my "binary function" is ST_Equals
. So really, I'm searching for a bunch of duplicate line strings. I don't feel like this information is relevant to the question at hand other than showing I can't simplify the problem down to easier to handle operations.