简体   繁体   中英

MySQL if condition then left join

I have a working Select at the bottom of the page. As you can see, it has 53 lines and, in my opinion, this is too much. I have been told me that there is an 'if' condition available in MySQL, but I have not able to make it work. The working Select unions 4 selects, because in each select, I need to join another table. Is it possible to join tables according to their content?

SELECT *
FROM (
    SELECT m.`identificator` , ml.id AS link_id, ml.parent, ml.type, 
            ml.destination, ml.disabled, ml.order, mld.`name` AS link_name, 
            mld.`alt` , mld.`title` , cpd.`slug` 
    FROM  `wf_menu` m
    LEFT JOIN  `wf_menu_link` ml ON m.`id` = ml.`menu_id` 
    LEFT JOIN  `wf_menu_link_desc` mld ON ml.`id` = mld.`link_id` 
    LEFT JOIN  `wf_cms_post_desc` cpd ON ml.destination = cpd.post_id
    WHERE mld.`lang_id` =1
    AND mld.`lang_id` = cpd.`lang_id` 
    AND (ml.`type` =  'page'
    OR ml.`type` =  'article')

    UNION

    SELECT m.`identificator` , ml.id AS link_id, ml.parent, ml.type, 
            ml.destination, ml.disabled, ml.order, mld.`name` AS link_name, 
            mld.`alt` , mld.`title` , cpd.`slug` 
    FROM  `wf_menu` m
    LEFT JOIN  `wf_menu_link` ml ON m.`id` = ml.`menu_id` 
    LEFT JOIN  `wf_menu_link_desc` mld ON ml.`id` = mld.`link_id` 
    LEFT JOIN  `wf_cms_category_desc` cpd ON ml.destination = cpd.category_id
    WHERE mld.`lang_id` =1
    AND mld.`lang_id` = cpd.`lang_id` 
    AND ml.`type` =  'cmscat'

    UNION

    SELECT m.`identificator` , ml.id AS link_id, ml.parent, ml.type, 
            ml.destination, ml.disabled, ml.order, mld.`name` AS link_name, 
            mld.`alt` , mld.`title` , spd.`slug` 
    FROM  `wf_menu` m
    LEFT JOIN  `wf_menu_link` ml ON m.`id` = ml.`menu_id` 
    LEFT JOIN  `wf_menu_link_desc` mld ON ml.`id` = mld.`link_id` 
    LEFT JOIN  `wf_shop_category_desc` spd ON ml.destination = spd.category_id
    WHERE mld.`lang_id` =1
    AND mld.`lang_id` = spd.`lang_id` 
    AND ml.`type` =  'shopcat'

    UNION

    SELECT m.`identificator` , ml.id AS link_id, ml.parent, ml.type, 
            ml.destination, ml.disabled, ml.order, mld.`name` AS link_name, 
            mld.`alt` , mld.`title` , 'link' as slug 
    FROM  `wf_menu` m
    LEFT JOIN  `wf_menu_link` ml ON m.`id` = ml.`menu_id` 
    LEFT JOIN  `wf_menu_link_desc` mld ON ml.`id` = mld.`link_id` 
    WHERE mld.`lang_id` =1
    AND ml.`type` =  'link'

) a
ORDER BY `order` DESC

I think you need to use Dynamic SQL. I mean, build your end SQL into a temporary variable and execute it:

set @query = (SELECT ...);
PREPARE st FROM @query;
EXECUTE st;

Your first case coould be something like:

SET @query= (SELECT CONCAT(GROUP_CONCAT(CONCAT('SELECT m.`identificator` , ml.id AS link_id, ml.parent, ml.type, 
            ml.destination, ml.disabled, ml.order, mld.`name` AS link_name, 
            mld.`alt` , mld.`title` , cpd.`slug` FROM  `wf_menu` m LEFT JOIN  `wf_menu_link` ml ON m.`id` = ml.`menu_id` ',
            CASE WHEN TTYPES.type='article' THEN 
                CONCAT('LEFT JOIN  `wf_menu_link_desc` mld ON ml.`id` = mld.`link_id` LEFT JOIN  `wf_cms_post_desc` cpd ON ml.destination = cpd.post_id WHERE mld.`lang_id` =1 AND mld.`lang_id` = cpd.`lang_id` AND (ml.`type` =  \'page\' OR ml.`type` =  \'',TTYPES.type,'\')')

            END )
SEPARATOR ' UNION '), ' SELECT NULL FROM wf_menu_link WHERE 1=2') FROM (SELECT DISTINCT wf_menu_link.`type` FROM wf_menu_link) TTYPES);

(You can complete the remainding cases)

Running that query will fill @query variable with a generated query. This generated query should be the same than you posted in your question. Then you can run it as you can see above in this answer.

This is an example/idea you have to complete it and/or check it works in your model.

You could possibly just do a single query, with each of the left joins in it, and sort out the resulting 'slug' column using IF statements. However this depends on exactly what you want output, and whether there are multiple matching rows on the other tables.

Something like this:-

SELECT m.identificator , ml.id AS link_id, ml.parent, ml.type, 
        ml.destination, ml.disabled, ml.order, mld.name AS link_name, 
        mld.alt , mld.title , cpd.slug 
FROM  wf_menu m
LEFT JOIN  wf_menu_link ml ON m.id = ml.menu_id 
LEFT JOIN  wf_menu_link_desc mld ON ml.id = mld.link_id 
LEFT JOIN  wf_cms_post_desc cpd ON ml.destination = cpd.post_id AND (ml.type = 'page' OR ml.type = 'article')
LEFT JOIN  wf_cms_category_desc cpd ON ml.destination = cpd.category_id AND ml.type =  'cmscat' AND mld.lang_id = cpd.lang_id 
LEFT JOIN  wf_shop_category_desc spd ON ml.destination = spd.category_id AND ml.type =  'shopcat' AND mld.lang_id = spd.lang_id 
WHERE mld.lang_id =1
AND mld.lang_id = cpd.lang_id 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM