tags:

views:

111

answers:

2

Hello, I want to write a SELECT statement as follows:

SELECT field_a 
FROM my_table
WHERE field_b IN (my_function(field_c)).

Is that possible?

my_function would have to return an array?

I'm using PostgreSQL 8.2

A: 

As long as my_function's return type is just a result set with the same type as field_b (like Varchar(20) or int), then you should be fine.

Correl
+4  A: 
SELECT  *
FROM    (
        SELECT  field_a, field_b, my_function(field_c) fc
        FROM    mytable
        ) q
WHERE   field_b = fc

The return type of your function should be SETOF (e. g. SETOF INT, SETOF VARCHAR etc.)

Note that you can use an IN style expression like this:

SELECT  field_a, field_b
FROM    mytable
WHERE   field_b IN (SELECT my_function(field_c))

, but if your function returns a complex type, the former style is preferrable, since you can compare to one field of the complex type and return the other within one query, like this:

FUNCTION my_function RETURNS SETOF anothertable

/* This will return a set of records of same layout as in table "anothertable" */

SELECT  field_a, field_b, fc.column1, fc.column2
FROM    (
        SELECT  field_a, field_b, my_function(field_c) fc
        FROM    mytable
        ) q
WHERE   field_b = fc.column1

We compare with column1 here and return both column1 and column2.

This would be impossible with a correlated subquery.

Quassnoi
You're right about the SETOF return type, but the example query could be simpler - "... WHERE field_b IN (SELECT my_function(field_c))".
Milen A. Radev
Simpler is not better. Subselects especially with a function would be a performance killer. A derived table is almost always preferred over a subselect.
HLGEM
@Milen: already there :)
Quassnoi
@HLGEM: performance will be the same for both queries.
Quassnoi