The problem with the expression you provided was that the intersection ()
part only calculated the overlap of C and B, notwithstanding if they are inside A or not. You have to add another overlap, pseudocode: overlap of A with ( overlap of B and C)
- you had only the part inside the paranthesis.
To create the overlap you're interested in, the expression looks like (for the area and percentage see below):
intersection (
$geometry ,
intersection(
buffer(
collect_geometries(
overlay_intersects(
'B',
$geometry
)
),
0
),
buffer(
collect_geometries(
overlay_intersects(
'C',
$geometry
)
),
0
)
)
)
Screenshot: A= black lines; B: blue; C: green; red: overlap calculated with the expression above:

So based on this, calculating the percentage of ovelapping for each polygon of A is easy - pseudocode: area of the overlap created above / area of each polygon of A * 100
. In fact, buffering by 0 is not necessary, you can leave this part away. Thus the expression to calculate the percentage looks like this:
area (
intersection (
$geometry ,
intersection(
collect_geometries(
overlay_intersects(
'B',
$geometry
)
),
collect_geometries(
overlay_intersects(
'C',
$geometry
)
)
)
)
)
/area($geometry)*100
Screenshot: the label is created dynamically with the expression above (+ a round()
to round to one decimal). Polygon A on the right (balck outlined) contains four overlapping areas (red), the polygon at the bottom left 2, the other two just one red area. The percentage is calculated as the sum of all red areas inside a polygon, whereas the area of the black outlined polygon A features is 100% for each polygon:

If however the percentage of ovelapping you need is not for each polygon of A, but for the area of the blue polygons that are within each polygon of A, than replace the last line /area($geometry)*100
with this expression:
/area (
intersection (
$geometry ,
collect_geometries(
overlay_intersects(
'B',
$geometry
)
)
)
)*100
After some tries, the final expression that works for the date of the OP includes the buffers of 0:
area (
buffer(
intersection (
$geometry ,
buffer (
intersection(
buffer(
collect_geometries(
overlay_intersects(
'B',
$geometry
)
),
0
),
buffer(
collect_geometries(
overlay_intersects(
'C',
$geometry
)
),0
)
),0
)
),0
)
)/area(
buffer(
collect_geometries(
overlay_intersects(
'B',
$geometry
)
),0
)
)*100