How to emulate full outer join in this query?

后端 未结 1 465
忘掉有多难
忘掉有多难 2021-01-27 14:08

So apparently mySQL doesn\'t support full outer join, but it\'s really what I need. I\'ve seen a bunch of blog posts and articles about emulating it with unions, but that remove

1条回答
  •  长情又很酷
    2021-01-27 14:48

    You basically do a Union of LEFT and RIGHT JOIN.

    You actually have interesting wrinkle in that you also want to limit the rows to 3. To solve that you need to

    • Limit both The "left" and "right" selects by 3
    • Then use the result of the UNION in a inline view
    • then Limit the union by 3 again

    UPDATE Sadly, unless I'm mistaken you can't do this directly in a UNION so you need to add another layer of inline views prior to the UNION

    The LIMITS inside the UNION will offer some performance benefit and then the limit after will give you the correct results.

    SELECT title, 
       teaser, 
       nid, 
       DATE, 
       image, 
       image_tid 
    FROM   (SELECT title, 
                   teaser, 
                   nid, 
                   DATE, 
                   image, 
                   image_tid,
                   created 
            FROM   (SELECT DISTINCT n.title, 
                                    nr.teaser, 
                                    n.nid, 
                                    Date_format(From_unixtime(n.created), 
                                    '%M %e, %Y') AS 
                                    DATE, 
                                    f.filepath 
                                    AS 
                                    image, 
                                    tn_img.tid 
                                    AS 
                                    image_tid 
                                           , 
                                    n.created 
                    FROM   node n 
                           JOIN node_revisions nr 
                             ON n.nid = nr.nid 
                           LEFT JOIN content_field_related_images cfri 
                             ON ( n.nid = cfri.nid 
                                  AND cfri.delta = 0 ) 
                           LEFT JOIN content_field_att_file cfaf 
                             ON cfri.field_related_images_nid = cfaf.nid 
                           LEFT JOIN files f 
                             ON cfaf.field_att_file_fid = f.fid 
                           JOIN term_node tn2 
                             ON n.nid = tn2.nid 
                           LEFT OUTER JOIN term_node tn_img 
                             ON cfri.field_related_images_nid = tn_img.nid 
                    WHERE  n.status = 1 
                           AND n.TYPE = 'article' 
                           AND nr.body LIKE '%kimberly-clark%' 
                           AND tn2.tid = 143 
                    ORDER  BY n.created DESC 
                    LIMIT  3) tleft 
            UNION 
            SELECT title, 
                   teaser, 
                   nid, 
                   DATE, 
                   image, 
                   image_tid,
                   created  
            FROM   (SELECT DISTINCT n.title, 
                                    nr.teaser, 
                                    n.nid, 
                                    Date_format(From_unixtime(n.created), 
                                    '%M %e, %Y') AS 
                                    DATE, 
                                    f.filepath 
                                    AS 
                                    image, 
                                    tn_img.tid 
                                    AS 
                                    image_tid 
                                           , 
                                    n.created 
                    FROM   node n 
                           JOIN node_revisions nr 
                             ON n.nid = nr.nid 
                           LEFT JOIN content_field_related_images cfri 
                             ON ( n.nid = cfri.nid 
                                  AND cfri.delta = 0 ) 
                           LEFT JOIN content_field_att_file cfaf 
                             ON cfri.field_related_images_nid = cfaf.nid 
                           LEFT JOIN files f 
                             ON cfaf.field_att_file_fid = f.fid 
                           JOIN term_node tn2 
                             ON n.nid = tn2.nid 
                           RIGHT OUTER JOIN term_node tn_img 
                             ON cfri.field_related_images_nid = tn_img.nid 
                    WHERE  n.status = 1 
                           AND n.TYPE = 'article' 
                           AND nr.body LIKE '%kimberly-clark%' 
                           AND tn2.tid = 143 
                    ORDER  BY n.created DESC 
                    LIMIT  3) tright) t 
    ORDER  BY created DESC 
    LIMIT  3 
    

    UPDATE Using spencer7593 and ypercube suggestions here's an alternative approach using two UNION ALL statements and no inline views.

    SELECT DISTINCT n.created, 
                    n.title, 
                    nr.teaser, 
                    n.nid, 
                    Date_format(From_unixtime(n.created), '%M %e, %Y') AS DATE, 
                    f.filepath                                         AS image, 
                    tn_img.tid                                         AS image_tid 
    FROM   node n 
           JOIN node_revisions nr 
             ON n.nid = nr.nid 
           LEFT JOIN content_field_related_images cfri 
             ON ( n.nid = cfri.nid 
                  AND cfri.delta = 0 ) 
           LEFT JOIN content_field_att_file cfaf 
             ON cfri.field_related_images_nid = cfaf.nid 
           LEFT JOIN files f 
             ON cfaf.field_att_file_fid = f.fid 
           JOIN term_node tn2 
             ON n.nid = tn2.nid 
           LEFT OUTER JOIN term_node tn_img 
             ON cfri.field_related_images_nid = tn_img.nid 
    WHERE  n.status = 1 
           AND n.TYPE = 'article' 
           AND nr.body LIKE '%kimberly-clark%' 
           AND tn2.tid = 143 
    
    UNION ALL 
    SELECT DISTINCT n.created, 
                    n.title, 
                    nr.teaser, 
                    n.nid, 
                    Date_format(From_unixtime(n.created), '%M %e, %Y') AS DATE, 
                    f.filepath                                         AS image, 
                    tn_img.tid                                         AS image_tid 
    FROM   node n 
           JOIN node_revisions nr 
             ON n.nid = nr.nid 
           LEFT JOIN content_field_related_images cfri 
             ON ( n.nid = cfri.nid 
                  AND cfri.delta = 0 ) 
           LEFT JOIN content_field_att_file cfaf 
             ON cfri.field_related_images_nid = cfaf.nid 
           LEFT JOIN files f 
             ON cfaf.field_att_file_fid = f.fid 
           JOIN term_node tn2 
             ON n.nid = tn2.nid 
           RIGHT JOIN term_node tn_img 
             ON cfri.field_related_images_nid = tn_img.nid 
    WHERE  n.status = 1 
           AND n.TYPE = 'article' 
           AND nr.body LIKE '%kimberly-clark%' 
           AND tn2.tid = 143 
           AND cfri.field_related_images_nid IS NULL 
    ORDER  BY 1 DESC 
    LIMIT 
    3 
    

    0 讨论(0)
提交回复
热议问题