Reputation: 1935
I have the following MySQL query:
SELECT * FROM (SELECT * FROM paper ORDER BY id DESC) paper_sorted,
(SELECT @pv := 26) initialisation
WHERE find_in_set(id, @pv)
AND length(@pv := concat(@pv, ',', last_id))
ORDER BY @pv ASC LIMIT 0,15
http://sqlfiddle.com/#!9/9e2df/24
This works perfectly fine in MySQL; however, I am working with a MariaDB database and this query is not working. Anyway to rewrite this for it to work for both MySQL and MariaDB?
Database schema:
CREATE TABLE paper (
id INT,
last_id INT
);
INSERT INTO paper VALUES (19, 0);
INSERT INTO paper VALUES (20, 19);
INSERT INTO paper VALUES (21, 20);
INSERT INTO paper VALUES (22, 21);
INSERT INTO paper VALUES (23, 19);
INSERT INTO paper VALUES (24, 23);
INSERT INTO paper VALUES (25, 23);
INSERT INTO paper VALUES (26, 24);
MariaDB v. 10.3.18; MySQL v. 5.7.27
This SQL query should get all the Parent IDs.
As in the example query, @pv
variable is 26, and thus gets 26->24->23->19.
However, this is not working for MariaDB. It's only returning one row, which is 26 in MariaDB. How to rewrite this query to work for both MariaDB and MySQL?
Upvotes: 0
Views: 780
Reputation: 2562
You should be able to rewrite the query as a Recursive CTE. These were added into MariaDB 10.2 and allow querying hierarchical data structures with SQL.
Something along these lines should work:
WITH RECURSIVE p AS (
SELECT * FROM paper WHERE id = 26
UNION
SELECT c.* FROM paper AS c, p WHERE p.last_id = c.id
) SELECT * FROM p ORDER BY id ASC LIMIT 15;
Edit: If you need the SQL to be backwards compatible with older versions, you can use a stored procedure to achieve the same result.
DELIMITER // ;
CREATE OR REPLACE PROCEDURE p1(IN id_in INT)
BEGIN
DECLARE i INT DEFAULT id_in;
CREATE OR REPLACE TEMPORARY TABLE results LIKE paper;
WHILE i IS NOT NULL DO
INSERT INTO results SELECT p.id, p.last_id FROM paper AS p WHERE p.id = i;
SET i = (SELECT r.last_id FROM results AS r WHERE r.id = i LIMIT 1);
END WHILE;
SELECT * FROM results;
DROP TEMPORARY TABLE results;
END;
//
DELIMITER ; //
Upvotes: 1