I have to do a very unusual Mysql query.
I have 1 Table with 2 listings over currently 5k lines that looks like this:
**Id** **Color** 2369 0 2370 2 2372 0 2373 1 2374 2 2375 2
And so on its all very basic, but now I have to filter it out in a specific order for example:
**Color** 2 0 1 2
In this Case the query should give me the Ids 2370 – 2374. These Ids should be saved in a php Array or separate PHP Variables. Array is preferred though.
My Question whats the best way to do this.
For those who might want to claim this Question as a duplicate, I have no idea of how to describe this procedure so I was unable to Google it.
Edit:
Example Order This Can be Anything:
**Color** 1. 2 2. 0 3. 1 4. 2
I want to Filter in which line the the first 2 comes like you see in my first code Block its the line with id 2370 after that the same with the 0
One line is depending on its bottom and top line
If I would change Replace the 0 in my Example with a 2 for example none of the id´s in the first code block would be true
I want to check every line from the first till the latest id if this order pops up
Advertisement
Answer
Disclaimer – A bad way to do this 😀 Consider this maybe only when you have to execute this manually or optimization is not an issue.
From your first example 2370 -> 2372
I took the assumption that your ids might skip some numbers but you would still want to match “the next row”, so firstly I created an ugly sub-table to get the id-pair of 4 consecutive ids
SELECT t1.id as t1_id, @sep := '-' as "id/color separator", @color_len := 1 as "color value length", @t2 := (SELECT CONCAT(id, @sep, color) FROM tbl WHERE id > t1.id ORDER BY id LIMIT 1) as "second row", @t2_sep := LOCATE(@sep, @t2) as "second id length", @t2_id := SUBSTRING(@t2, 1, @t2_sep - 1) as t2_id, @t3 := (SELECT CONCAT(id, @sep, color) FROM tbl WHERE id > @t2_id ORDER BY id LIMIT 1) as "third row", @t3_sep := LOCATE(@sep, @t3) as "third id length", @t3_id := SUBSTRING(@t3, 1, @t3_sep - 1) as t3_id, @t4 := (SELECT CONCAT(id, @sep, color) FROM tbl WHERE id > @t3_id ORDER BY id LIMIT 1) as "forth row", @t4_sep := LOCATE(@sep, @t4) as "forth id length", @t4_id := SUBSTRING(@t4, 1, @t4_sep - 1) as t4_id, t1.color as t1_color, SUBSTRING(@t2, @t2_sep + 1, @color_len) as t2_color, SUBSTRING(@t3, @t3_sep + 1, @color_len) as t3_color, SUBSTRING(@t4, @t4_sep + 1, @color_len) as t4_color FROM tbl as t1 WHERE t1.color = 2;
and then filtered out only the rows matching the color-ordering you wanted
SELECT t.t1_id, t.t2_id, t.t3_id, t.t4_id FROM ( /* previous query */ ) as t WHERE t.t2_color = 0 AND t.t3_color = 1 AND t.t4_color = 2;
Now if you would normalize your ids so they wount skip numbers either on saving/deleting records or rearranging over time, the solution would be simple:
SELECT t1.id, t2.id, t3.id, t4.id FROM tbl as t1 INNER JOIN tbl as t2 ON t2.id = t1.id + 1 AND t2.color = 0 INNER JOIN tbl as t3 ON t3.id = t1.id + 2 AND t3.color = 1 INNER JOIN tbl as t4 ON t4.id = t1.id + 3 AND t4.color = 2 WHERE t1.color = 2