@
@
@coderok2016-06-07 12:26:06
PostgreSQL
@coderok, 2016-06-07 12:26:06

How to filter search results in PostgreSQL?

Good afternoon!
For several days now I can not solve the problem with the search.
There are such tables:

contact table

id |last_modified       |date_create         |
---|--------------------|--------------------|
1  |2016-06-03 11:59:20 |2016-06-03 11:59:20 |
2  |2016-06-03 11:59:20 |2016-06-03 11:59:20 |
3  |2016-06-03 11:59:20 |2016-06-03 11:59:20 |

custom_field table

id |element_id |element_type |enum_code  |
---|-----------|-------------|-----------|
1  |1          |0            |First Name |
2  |1          |0            |Last Name  |
3  |1          |0            |Company    |
4  |1          |0            |Phone      |
5  |1          |0            |Email      |
6  |2          |0            |First Name |
7  |2          |0            |Last Name  |
8  |2          |0            |Company    |
9  |2          |0            |Phone      |
10 |2          |0            |Email      |
11 |3          |0            |First Name |
12 |3          |0            |Last Name  |
13 |3          |0            |Company    |
14 |3          |0            |Phone      |
15 |3          |0            |Email      |

custom_field_value table

id |custom_field_id |enum_value_code |value                     |last_modified       |
---|----------------|----------------|--------------------------|--------------------|
1  |1               |First Name      |John                      |2016-06-03 11:59:20 |
2  |2               |Last Name       |Galt                      |2016-06-03 11:59:20 |
3  |3               |Company         |XYZ Inc                   |2016-06-03 11:59:20 |
4  |4               |Work            |(245) 864-2662            |2016-06-03 11:59:20 |
5  |4               |Mobile          |(708) 744-5912            |2016-06-03 11:59:20 |
6  |4               |Home            |(634) 937-4992            |2016-06-03 11:59:20 |
7  |5               |Work            |[email protected]       |2016-06-03 11:59:20 |
8  |5               |Home            |[email protected]          |2016-06-03 11:59:20 |
10 |7               |Last Name       |Doe                       |2016-06-03 11:59:20 |
11 |8               |Company         |Dream Company             |2016-06-03 11:59:20 |
12 |9               |Work            |(313) 127-6212            |2016-06-03 11:59:20 |
13 |9               |Mobile          |(176) 884-1084            |2016-06-03 11:59:20 |
14 |9               |Home            |(273) 997-2727            |2016-06-03 11:59:20 |
15 |10              |Work            |[email protected]       |2016-06-03 11:59:20 |
16 |10              |Home            |[email protected] |2016-06-03 11:59:20 |
17 |11              |First Name      |Suzy                      |2016-06-03 11:59:20 |
18 |12              |Last Name       |Corn                      |2016-06-03 11:59:20 |
19 |13              |Company         |PipeIt                    |2016-06-03 11:59:20 |
20 |14              |Work            |(180) 183-9772            |2016-06-03 11:59:20 |
21 |14              |Mobile          |(534) 840-1223            |2016-06-03 11:59:21 |
22 |14              |Home            |(547) 583-4643            |2016-06-03 11:59:21 |
23 |15              |Work            |[email protected]        |2016-06-03 11:59:21 |
24 |15              |Home            |[email protected]     |2016-06-03 11:59:21 |
9  |6               |First Name      |John                      |2016-06-03 11:59:20 |

The contact has fields that are in the custom_field table. The values ​​of these fields are in the custom_field_value table.
Prior to this, the search worked through ILIKE '%some text%'and as a result I received a contact and all its fields.
The problem with this solution is that we are looking for a match on a single field.
If I, for example, search for 'John', I will find two contacts. But if I search for 'John XYZ Inc', the contact will not be found.
So I changed the query a bit to ILIKE ANY(array['%John%', '%XYZ Inc%'])
This query will also return two contacts, but I only want the contact that has both 'John' and 'XYZ Inc' in the fields.
That is, somehow filter the search results, but I do not know how to do this through SQL.
The script for creating tables can be taken from the link: Script
Request:
SELECT
   c.id,
   c.last_modified,
   c.date_create,
   cf.id as cf_id,
   cf.enum_code,
   cfv.id as cfv_id,
   cfv.enum_value_code,
   cfv.value,
   cfv.last_modified as cfv_last_modified   
FROM
   contact c   
LEFT JOIN
   custom_field cf 
      ON (
         cf.element_id=c.id 
         AND cf.element_type=0
      )  
LEFT JOIN
   custom_field_value cfv 
      ON cfv.custom_field_id=cf.id,
   (SELECT
      DISTINCT sub_cf.element_id    
   FROM
      custom_field_value sub_cfv    
   INNER JOIN
      custom_field sub_cf 
         ON sub_cfv.custom_field_id = sub_cf.id    
   INNER JOIN
      contact sub_c 
         ON sub_c.id = sub_cf.element_id    
   WHERE
      sub_cf.element_type=0 
      AND sub_cfv.value ILIKE ANY(ARRAY['%John%', '%XYZ%'])    
   ORDER BY
      sub_cf.element_id DESC OFFSET 0 LIMIT 50) AS sub_search  
WHERE
   sub_search.element_id=c.id 
ORDER BY
   c.last_modified DESC;

Answer the question

In order to leave comments, you need to log in

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question