To be noticed: Area and length measurements in EPSG:4326 and do not give reasonable results but that's dealt with many other quesions https://gis.stackexchange.com/search?q=epsg%3A4326+area+
Re-ordering the multipolygon members by area can be done by exploding the multipolygon with ST_Dump, ordering the primitive polygons by the result of ST_Area and finally building a new multipolygon from the sorted primitives with ST_Collect. I do not know how reliable that is because by definition the order of members in geometry collections, including MultiPolygons, does not matter.
Test 1 by sorting members by area in ascending order:
SELECT ST_AsText(ST_Collect(b.primitive_geom)) AS collected_geometry
from (
SELECT (a.p_geom).geom as primitive_geom, ST_Area((a.p_geom).geom) as sub_area
FROM (
SELECT ST_Dump(
ST_GeometryFromText('MULTIPOLYGON ((( 220 500, 220 540, 260 540, 260 500, 220 500 )), (( 280 460, 280 540, 360 540, 360 460, 280 460 )))'))
as p_geom) AS a ORDER BY sub_area ASC) AS b;
Result:
MULTIPOLYGON(((220 500,220 540,260 540,260 500,220 500)),((280 460,280 540,360 540,360 460,280 460)))
Test 2 by sorting members by area in descending order:
SELECT ST_AsText(ST_Collect(b.primitive_geom)) AS collected_geometry
from (
SELECT (a.p_geom).geom as primitive_geom, ST_Area((a.p_geom).geom) as sub_area
FROM (
SELECT ST_Dump(
ST_GeometryFromText('MULTIPOLYGON ((( 220 500, 220 540, 260 540, 260 500, 220 500 )), (( 280 460, 280 540, 360 540, 360 460, 280 460 )))'))
as p_geom) AS a ORDER BY sub_area DESC) AS b;
Result:
MULTIPOLYGON(((280 460,280 540,360 540,360 460,280 460)),((220 500,220 540,260 540,260 500,220 500)))
Finally a test with your geometry that is actually a multipolygon with two polygons, one with a hole and another without.
SELECT ST_AsText(ST_Collect(b.primitive_geom)) AS collected_geometry
from (
SELECT (a.p_geom).geom as primitive_geom, ST_Area((a.p_geom).geom) as sub_area
FROM (
SELECT ST_Dump(
ST_GeometryFromText('MULTIPOLYGON (((40 40, 20 45, 45 30, 40 40)), ((20 35, 10 30, 10 10, 30 5, 45 20, 20 35), (30 20, 20 15, 20 25, 30 20)))'))
as p_geom) AS a ORDER BY sub_area ASC) AS b;
Result:
MULTIPOLYGON(((40 40,20 45,45 30,40 40)),((20 35,10 30,10 10,30 5,45 20,20 35),(30 20,20 15,20 25,30 20)))
I guess that you just did not notice that one polygon ring is a hole.
( 30 20, 20 15, 20 25, 30 20 )
is a hole in another polygon.select st_isvalidreason(st_geomfromtext('MULTIPOLYGON (((20 35, 10 30, 10 10, 30 5, 45 20, 20 35)), ((30 20, 20 15, 20 25, 30 20)), ((40 40, 20 45, 45 30, 40 40)))'))
. In GeometryCollection that would be doable. I fixed the syntax in question but geometry is still invalid.select st_astext (st_makevalid (st_geomfromtext ('MULTIPOLYGON (((20 35, 10 30, 10 10, 30 5, 45 20, 20 35)), ((30 20, 20 15, 20 25, 30 20)), ( (40 40, 20 45, 45 30, 40 40))) ')))
I get backMULTIPOLYGON(((20 35,45 20,30 5,10 10,10 30,20 35),(30 20,20 25,20 15,30 20)),((40 40,45 30,20 45,40 40)))
which has two polygon members, one with a hole and one without. I guess that this is not the result that you want to show for me.