MySQL - Elegant and flexible way to simulate INTERSECT operator

By xngo on April 7, 2019

Overview

In MySQL, INTERSECT operator doesn't exist. However, you can simulate it. But, let's first start to define what intersect means. It returns any distinct values that are returned by both the query on the left and right sides. Here is the Venn diagram representing the intersect.

Venn diagram representing the intersect

Get the intersect

Obviously, there multiple ways to get the intersect. However, the most elegant and flexible way I found is to use UNION ALL and GROUP BY. The idea is to union all results and count how many times the value repeat itself. If it is more than once, then that value must exist in more than 1 table. Here is an example with 3 set of data(sub-queries).

SELECT * FROM
    (
        (SELECT DISTINCT ticker_id FROM Indicator WHERE (name='price' AND value>=2))
            UNION ALL
        (SELECT DISTINCT ticker_id FROM Indicator WHERE (name='volume' AND value>=100000))
            UNION ALL
        (SELECT DISTINCT ticker_id FROM Indicator WHERE (name='overlap_sma_dir' AND value>0))
    ) AS tmp
GROUP BY ticker_id HAVING COUNT(*)=3

Note: Each sub-query should return unique values. Hence, I put DISTINCT ticker_id. Otherwise, HAVING COUNT(*) will not work.

As you can see, it is visually appealing, easy to understand and not convoluted.

About the author

Xuan Ngo is the founder of OpenWritings.net. He currently lives in Montreal, Canada. He loves to write about programming and open source subjects.