Hi, If we forget the first method which i mis-adviced, i can give a third which is generic.
suppose that you have an indexed "type" column on each table (what i did). You can work with 3 variables. If they are different, you query for a join, if they are equal, you transform the join to a simple query. The only condition is to add a where clause a the column "type" which will retreive empty set for the non selected conditions. Example :! set @cat1:='news'; set @cat2:='faq'; set @cat3:='forum'; mysql> select id,@cat1 as selected, type from news where [EMAIL PROTECTED] -> union select id,@cat2 as selected, type from faq where [EMAIL PROTECTED] -> union select id,@cat3 as selected, type from forum where [EMAIL PROTECTED]; +------+----------+-------+ | id | selected | type | +------+----------+-------+ | 1 | news | news | | 2 | faq | faq | | 3 | forum | forum | +------+----------+-------+ 3 rows in set (0.00 sec) When you have only one value, the same query gives : **************************************************** mysql> set @cat1='news'; set @cat2='news'; set @cat3='news'; Query OK, 0 rows affected (0.00 sec) here the 3 variables are the same, so 2 queries will find an empty set. mysql> select id,@cat1 as selected, type from news where [EMAIL PROTECTED] -> union select id,@cat2 as selected, type from faq where [EMAIL PROTECTED] -> union select id,@cat3 as selected, type from forum where [EMAIL PROTECTED]; +------+----------+------+ | id | selected | type | +------+----------+------+ | 1 | news | news | +------+----------+------+ 1 row in set (0.00 sec) performance will not be affected since the index will be used for non used tables. Hope that helps :o) Mathias Selon Sebastian <[EMAIL PROTECTED]>: > Michael Stassen wrote: > > > [EMAIL PROTECTED] wrote: > > > >> Hi Sebastian; > >> There is always crazy things somewhere. > >> I'll give you two methods for that : > >> > >> mysql> select id,'news' as selected, type from news > >> -> union select id,'faq' as selected, type from faq > >> -> union select id,'forum' as selected, type from forum; > >> +------+----------+-------+ > >> | id | selected | type | > >> +------+----------+-------+ > >> | 1 | news | news | > >> | 2 | faq | faq | > >> | 3 | forum | forum | > >> +------+----------+-------+ > >> 3 rows in set (0.00 sec) > >> > >> > >> FIRST CRAZY METHOD : > >> ************************* > >> mysql> set @cat='news'; > >> Query OK, 0 rows affected (0.00 sec) > >> > >> mysql> select * from ( > >> -> select id,'news' as selected, type from news > >> -> union select id,'faq' as selected, type from faq > >> -> union select id,'forum' as selected, type from forum > >> -> ) Temp > >> -> where [EMAIL PROTECTED]; > >> +------+----------+------+ > >> | id | selected | type | > >> +------+----------+------+ > >> | 1 | news | news | > >> +------+----------+------+ > >> 1 row in set (0.00 sec) > >> > >> > >> SECOND CRAZY METHOD (I prefer): > >> ************************* > >> > >> set @cat := 'news'; > >> set @sql:=concat('select id,','''',@cat,'''',' as selected from ',@cat); > >> select @sql; > >> prepare stmt from @sql ; > >> execute stmt; > >> > >> +------+----------+ > >> | id | selected | > >> +------+----------+ > >> | 1 | news | > >> +------+----------+ > >> 1 row in set (0.00 sec) > >> > >> deallocate prepare stmt; > >> > >> > >> ********* another click with ?cat=faq > >> > >> set @cat := 'faq'; > >> set @sql:=concat('select id,','''',@cat,'''',' as selected from ',@cat); > >> select @sql; > >> prepare stmt from @sql ; > >> execute stmt; > >> > >> mysql> execute stmt; > >> +------+----------+ > >> | id | selected | > >> +------+----------+ > >> | 2 | faq | > >> +------+----------+ > >> 1 row in set (0.00 sec) > >> > >> deallocate prepare stmt; > >> > >> OTHER CRAZY METHODS - coming emails :o) > >> -------------------- > >> > >> A+ > >> Mathias > > > > > > The first method is horribly inefficient (and requires mysql 4.1+). > > It reads all 3 tables, unions the resulting rows, checks for (and > > removes) duplicate rows, then finally throws away roughly 2/3 of the > > results (the rows from the 2 unwanted tables. Compare that to the > > simple query which only addresses the 1 desired table. Mathias is > > aware of this, which is why he gives the second method. It creates > > the simple, one-table query using the value of $cat to choose which > > table. > > > > The big problem here is that neither of these methods actually do what > > you asked for. That is, neither works if $cat is not set. With both > > methods, you will get no rows unless $cat is set. In fact, the second > > method will give a syntax eror, as there will be no table name in the > > FROM clause. > > > > Now, I never said this couldn't be done in SQL. Assuming $cat is > > already set, the statement in $sql below should do what you asked for: > > > > $sql = "SELECT id, 'news' AS type, .... FROM news > > WHERE ($cat = '' OR $cat = 'news') > > UNION > > SELECT id, 'faq' AS type, .... FROM faq > > WHERE ($cat = '' OR $cat = 'faq') > > UNION > > SELECT id, 'forum' AS type, .... FROM forum > > WHERE ($cat = '' OR $cat = 'forum')" > > > > MySQL's optimizer should be smart enough to notice that if $cat is > > set, 2 of the 3 unioned queries will have impossible WHERE clauses, so > > those queries will be skipped, making this relatively efficient. > > > > Even though this works, though, I think it's a bit of a hack. It's > > clever SQL which allows two separate queries to masquerade as one, > > based on the value of $cat. I really think the simple, separate query > > solution I sent in my previous message > > > > if ($cat == 'news' or $cat == 'faq' or $cat == 'forum') > > { > > $sql = "SELECT id, '$cat' AS type, ... FROM $cat"; > > } > > else > > { > > $sql = " SELECT id, 'news' AS type, .... FROM news > > UNION > > SELECT id, 'faq' AS type, .... FROM faq > > UNION > > SELECT id, 'forum' AS type, .... FROM forum"; > > } > > > > is better, as it is clearer what we are doing (one query if we know > > the table, three queries unioned if we don't), so it should be easier > > to understand and maintain down the road (by you or the next guy). > > > > Michael > > you just gave me an idea.. maybe this is better: > > SET @cat = '$cat'; > > SELECT id, 'news' AS type, > WHERE [expression...] AND (@cat = 'news' OR @cat = '') > > UNION > SELECT id, 'faq' AS type, > WHERE [expression...] AND (@cat = 'faq' OR @cat = '') > > UNION > [SELECT ........] > > works regardless if $cat is set or not. > > -- MySQL General Mailing List For list archives: http://lists.mysql.com/mysql To unsubscribe: http://lists.mysql.com/[EMAIL PROTECTED]