SQL Server CROSS APPLY clause allows you to perform a correlated inner join (lateral join) often using a table-valued function or subquery. Correlated means that the right operand of a join clause contains a reference to the left operand.
In MariaDB you can use the CROSS JOIN LATERAL clause (still in progress, see https://jira.mariadb.org/browse/MDEV-19078).
Consider a sample data:
CREATE TABLE colors (name VARCHAR(30), arr VARCHAR(30)); CREATE TABLE chars (c CHAR(1)); INSERT INTO colors VALUES ('Green', '["g","r","e","e","n"]'); INSERT INTO colors VALUES ('Red', '["r","e","d"]'); INSERT INTO colors VALUES ('Black', NULL); INSERT INTO chars VALUES ('r'); INSERT INTO chars VALUES ('e'); INSERT INTO chars VALUES ('n');
SQL Server:
-- Duplicate each 'colors' line for every row returned by table-valued function SELECT name, value FROM colors CROSS APPLY OPENJSON(colors.arr) WITH (value CHAR '$') t;
Result:
name | value |
Green | g |
Green | r |
Green | e |
Green | e |
Green | n |
Red | r |
Red | e |
Red | d |
Note that 'Black' row is not returned by the query as the table-valued function returns NULL for it.
In MariaDB you can use CROSS JOIN or even INNER JOIN. Note that LATERAL keyword is not allowed for joins with table-valued functions:
MariaDB:
-- Duplicate each 'colors' line for every row returned by table-valued function SELECT name, value FROM colors CROSS JOIN JSON_TABLE(colors.arr, '$[*]' COLUMNS (value CHAR(1) PATH '$')) t; -- INNER JOIN can be also used SELECT name, value FROM colors INNER JOIN JSON_TABLE(colors.arr, '$[*]' COLUMNS (value CHAR(1) PATH '$')) t;
Result:
name | value |
Green | g |
Green | r |
Green | e |
Green | e |
Green | n |
Red | r |
Red | e |
Red | d |
Now let's perform CROSS APPLY using a subquery:
SQL Server:
SELECT name, c FROM colors CROSS APPLY (SELECT c FROM chars WHERE CHARINDEX(chars.c, colors.name) <> 0) c; -- INNER JOIN returns the same result SELECT name, c FROM colors INNER JOIN chars ON CHARINDEX(chars.c, colors.name) <> 0;
Result:
name | c |
Green | r |
Green | e |
Green | n |
Red | r |
Red | e |
In MariaDB we now have to use LATERAL keyword for the correlated subquery:
MariaDB:
-- Join fails without LATERAL keyword SELECT name, c FROM colors CROSS JOIN (SELECT c FROM chars WHERE INSTR(colors.name, chars.c) <> 0) c; -- ERROR 1054 (42S22): Unknown column 'colors.name' in 'where clause' -- Now with LATERAL SELECT name, c FROM colors CROSS JOIN LATERAL (SELECT c FROM chars WHERE INSTR(colors.name, chars.c) <> 0) c;
Result:
name | c |
Green | r |
Green | e |
Green | n |
Red | r |
Red | e |
For more information, see SQL Server to MariaDB Migration.