To get the same row more than once you need to join in another table. I suggest to create, only once(!), a helper table. This table will just contain a series of natural numbers (1, 2, 3, 4, ... etc). Such a table can be useful for many other purposes.
Here is the script to create it:
create table seq (num int);
insert into seq values (1),(2),(3),(4),(5),(6),(7),(8);
insert into seq select num+8 from seq;
insert into seq select num+16 from seq;
insert into seq select num+32 from seq;
insert into seq select num+64 from seq;
/* continue doubling the number of records until you feel you have enough */
For the task at hand it is not necessary to add many records, as you only need to make sure you never have more repetitions in your in condition than in the above seq table. I guess 128 will be good enough, but feel free to double the number of records a few times more.
Once you have the above, you can write queries like this:
select province_id,
name,
@pos := instr(@in2 := insert(@in2, @pos+1, 1, '#'),
concat(',',province_id,',')) ord
from (select @in := '0,1,2,3,1,0', @in2 := @in, @pos := 10000) init
inner join provinces
on find_in_set(province_id, @in)
inner join seq
on num <= length(replace(@in, concat(',',province_id,','),
concat(',+',province_id,',')))-length(@in)
order by ord asc
Output for the sample data and sample in list:
| province_id | name | ord |
|-------------|--------|-----|
| 1 | name 1 | 2 |
| 2 | name 2 | 4 |
| 3 | name 3 | 6 |
| 1 | name 1 | 8 |
SQL Fiddle
How it works
You need to put the list of values in the assignment to the variable @in. For it to work, every valid id must be wrapped between commas, so that is why there is a dummy zero at the start and the end.
By joining in the seq table the result set can grow. The number of records joined in from seq for a particular provinces record is equal to the number of occurrences of the corresponding province_id in the list @in.
There is no out-of-the-box function to count the number of such occurrences, so the expression at the right of num <= may look a bit complex. But it just adds a character for every match in @in and checks how much the length grows by that action. That growth is the number of occurrences.
In the select clause the position of the province_id in the @in list is returned and used to order the result set, so it corresponds to the order in the @in list. In fact, the position is taken with reference to @in2, which is a copy of @in, but is allowed to change:
While this @pos is being calculated, the number at the previous found @pos in @in2 is destroyed with a # character, so the same province_id cannot be found again at the same position.