Now that was fun and educational. :-)

I like the third approach, but theres an added problem to the whole thing.
This query is just a part of a bigger search.

The tables, job and color and other fields, which will also be searchable. I
am trying to automate the whole process, i mean, the user sees a combo for
the fields and a text input, and he can add as many fields as he wants, even
duplicated ones, like the two colors problem.

I am trying to build a super query that contains all the searches the user
wants to do on the tables. Its a stupid job.

I understand its an ingrate, and probably stupid, question, but for complex
searches like the one i mentioned, is there a line of thought i should
consider? I mean, it surely has been done and efficiently, so i am not
exactly inventing the wheel here.

Its what i said, imagine two/three tables, all joinable by common ids, and
allow the user to say "i want to search the name of the job, contains color1
and color2, is from client x and has the perimeter greater than 100". I am
teaching php how to do queries all by myself. :-P

Thank you all for the great suggestions.


Pag


On Wed, Dec 17, 2008 at 7:08 PM, Gavin Towey <ga...@swishmark.com> wrote:

> Three solutions, the first one is not recommended I just showed it for fun
> -- I think the last one is the most efficient:
>
> mysql> show create table job \G
> *************************** 1. row ***************************
>      Table: job
> Create Table: CREATE TABLE `job` (
>  `job_id` int(10) unsigned NOT NULL auto_increment,
>  `name` varchar(12) default NULL,
>  PRIMARY KEY  (`job_id`)
> ) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=latin1
> 1 row in set (0.00 sec)
>
> mysql> show create table color \G
> *************************** 1. row ***************************
>      Table: color
> Create Table: CREATE TABLE `color` (
>  `color_id` int(10) unsigned NOT NULL auto_increment,
>  `color` varchar(32) default NULL,
>  `job_id` int(10) unsigned default NULL,
>  PRIMARY KEY  (`color_id`)
> ) ENGINE=InnoDB AUTO_INCREMENT=9 DEFAULT CHARSET=latin1
> 1 row in set (0.02 sec)
>
>
> mysql> select * from job;
> +--------+-------+
> | job_id | name  |
> +--------+-------+
> |      1 | job 1 |
> |      2 | job 2 |
> |      3 | job3  |
> +--------+-------+
> 3 rows in set (0.00 sec)
>
> mysql> select * from color;
> +----------+---------+--------+
> | color_id | color   | job_id |
> +----------+---------+--------+
> |        1 | yellow  |      1 |
> |        2 | cyan    |      1 |
> |        3 | black   |      1 |
> |        4 | cyan    |      2 |
> |        5 | magenta |      2 |
> |        6 | black   |      2 |
> |        7 | yellow  |      2 |
> |        8 | cyan    |      3 |
> +----------+---------+--------+
> 8 rows in set (0.00 sec)
>
> Method #1
>
> mysql> select job_id, GROUP_CONCAT(color) as colors FROM job j JOIN color c
> USING (job_id) GROUP BY job_id HAVING colors LIKE '%cyan%magenta';
> +--------+---------------------------+
> | job_id | colors                    |
> +--------+---------------------------+
> |      2 | black,yellow,cyan,magenta |
> +--------+---------------------------+
> 1 row in set (0.01 sec)
>
>
> Method #2
> SELECT j.job_id, c1.color, c2.color FROM job j JOIN color c1 ON
> j.job_id=c1.job_id AND c1.color='cyan' JOIN color c2 ON j.job_id=c2.job_id
> AND c2.color='magenta';
> +--------+-------+---------+
> | job_id | color | color   |
> +--------+-------+---------+
> |      2 | cyan  | magenta |
> +--------+-------+---------+
> 1 row in set (0.00 sec)
>
> Method #3
> mysql> SELECT job_id, BIT_OR(CASE WHEN c.color='cyan' THEN 1 WHEN
> c.color='magenta' THEN 2 END) as colors  FROM job j JOIN color c USING
> (job_id) GROUP BY job_id HAVING colors=3;
> +--------+--------+
> | job_id | colors |
> +--------+--------+
> |      2 |      3 |
> +--------+--------+
> 1 row in set (0.00 sec)
>
>

Reply via email to