A combination of both ST_LineMerge and ST_Dump should give you the result that you want.
First apply ST_LineMerge to combine single line intersections, then ST_Dump to break apart the multi-linestrings.
If you have linestrings that go through an intersection without breaking you will also need to use ST_Node to segment the lines at the intersections.
An example query is
SELECT id, (dump_set).path AS line_part, ST_AsEWKT((dump_set).geom) AS line_string
FROM (
SELECT id, ST_Dump(ST_LineMerge(ST_Node(geom))) AS dump_set
FROM (VALUES
(1, 'MULTILINESTRING((0 10, 10 10),(10 0, 10 10),(10 0, 20 0))'::Geometry),
(2, 'MULTILINESTRING((0 10, 10 10),(10 10, 10 20),(10 0, 10 10))'::Geometry),
(3, 'MULTILINESTRING((0 10, 10 10),(10 10, 10 20),(10 0, 10 10),(10 0, 20 0))'::Geometry),
(4, 'MULTILINESTRING((0 10, 10 10, 10 20),(10 0, 10 10),(10 0, 20 0))'::Geometry)
)Lines(id,geom)
) AS dump_results;
Stepping through each part of the operation using the 4th row from above.
-- Multi line string composed of three parts. Intersection between first part and second at 10 10
SELECT ST_AsEWKT(
ST_Node(geom) -- Splits part one at 10 10
)
FROM ( VALUES(4, 'MULTILINESTRING((0 10, 10 10, 10 20),(10 0, 10 10),(10 0, 20 0))'::Geometry) )Lines(id,geom);
-- RESULT: "MULTILINESTRING( (0 10,10 10) , (10 10,10 20) , (10 10,10 0) , (10 0,20 0) )"
SELECT ST_AsEWKT(
ST_LineMerge( -- merges parts 3 and 4 at 10 0
ST_Node(geom)
)
)
FROM ( VALUES(4, 'MULTILINESTRING((0 10, 10 10, 10 20),(10 0, 10 10),(10 0, 20 0))'::Geometry) )Lines(id,geom);
-- RESULT: "MULTILINESTRING( (0 10,10 10) , (10 10,10 20) , (10 10,10 0,20 0) )"
SELECT ST_AsEWKT(
(
ST_Dump ( -- Returns the components of the multi linestring in an geometry_dump type
ST_LineMerge(
ST_Node(geom)
)
)
).geom -- Extracts the geometry component of the geometry_dump type
)
FROM ( VALUES(4, 'MULTILINESTRING((0 10, 10 10, 10 20),(10 0, 10 10),(10 0, 20 0))'::Geometry) )Lines(id,geom);
-- RESULT:
-- "LINESTRING(0 10,10 10)"
-- "LINESTRING(10 10,10 20)"
-- "LINESTRING(10 10,10 0,20 0)"