### Apache Airflow version

Other Airflow 2 version (please specify below)

### What happened

If you have an `ExternalTaskSensor` that uses `external_task_group_id` to wait on a `TaskGroup`, and if that `TaskGroup` contains any [mapped tasks](https://airflow.apache.org/docs/apache-airflow/2.3.0/concepts/dynamic-task-mapping.html), the sensor will be stuck waiting forever even after the task group is successful.

### What you think should happen instead

`ExternalTaskSensor` should be able to wait on `TaskGroup`s, regardless of whether or not that group contains mapped tasks.

### How to reproduce

```
#!/usr/bin/env python3
import datetime
import logging

from airflow.decorators import dag, task
from airflow.operators.empty import EmptyOperator
from airflow.sensors.external_task import ExternalTaskSensor
from airflow.utils.task_group import TaskGroup


logger = logging.getLogger(__name__)


@dag(
    schedule_interval='@daily',
    start_date=datetime.datetime(2023, 4, 17),
)
def task_groups():
    with TaskGroup(group_id='group'):
        EmptyOperator(task_id='operator1') >> EmptyOperator(task_id='operator2')

    with TaskGroup(group_id='mapped_tasks'):
        @task
        def get_tasks():
            return [1, 2, 3]

        @task
        def process(x):
            print(x)

        process.expand(x=get_tasks())

    ExternalTaskSensor(
        task_id='wait_for_normal_task_group',
        external_dag_id='task_groups',
        external_task_group_id='group',
        poke_interval=3,
        check_existence=True,
    )
    ExternalTaskSensor(
        task_id='wait_for_mapped_task_group',
        external_dag_id='task_groups',
        external_task_group_id='mapped_tasks',
        poke_interval=3,
        check_existence=True,
    )


task_groups()
```

### Operating System

CentOS Stream 8

### Versions of Apache Airflow Providers

N/A

### Deployment

Other

### Deployment details

Standalone

### Anything else

I think the bug is [here](https://github.com/apache/airflow/blob/731ef3d692fc7472e245f39f3e3e42c2360cb769/airflow/sensors/external_task.py#L364):
```
        elif self.external_task_group_id:
            external_task_group_task_ids = self.get_external_task_group_task_ids(session)
            count = (
                self._count_query(TI, session, states, dttm_filter)
                .filter(TI.task_id.in_(external_task_group_task_ids))
                .scalar()
            ) / len(external_task_group_task_ids)
```
If the group contains mapped tasks, `external_task_group_ids` only contains a list of task names (not expanded to include mapped task indices), but the `count` will count all mapped instances.  This returns a larger value than the calling function expects to receive when it checks for `count_allowed == len(dttm_filter)`, so `poke` always returns `False`.

### Are you willing to submit PR?

- [ ] Yes I am willing to submit a PR!

### Code of Conduct

- [X] I agree to follow this project's [Code of Conduct](https://github.com/apache/airflow/blob/main/CODE_OF_CONDUCT.md)

"""
    Tests clearing across multiple DAGs that have cyclic dependencies. AirflowException should be
    raised.
    """
    dag_bag = dag_bag_cyclic(10)
    run_tasks(dag_bag)
    dag_0 = dag_bag.get_dag("dag_0")
    task_a_0 = dag_0.get_task("task_a_0")
    with pytest.raises(AirflowException, match="Maximum recursion depth 3"):
        clear_tasks(dag_bag, dag_0, task_a_0)
def test_external_task_marker_cyclic_shallow(dag_bag_cyclic):
    """
    Tests clearing across multiple DAGs that have cyclic dependencies shallower
    than recursion_depth
    """
    dag_bag = dag_bag_cyclic(2)
    run_tasks(dag_bag)
    dag_0 = dag_bag.get_dag("dag_0")
    task_a_0 = dag_0.get_task("task_a_0")
    tis = clear_tasks(dag_bag, dag_0, task_a_0, dry_run=True)
    assert [
        ("dag_0", "task_a_0"),
        ("dag_0", "task_b_0"),
        ("dag_1", "task_a_1"),
        ("dag_1", "task_b_1"),
        ("dag_2", "task_a_2"),
        ("dag_2", "task_b_2"),
    ] == sorted((ti.dag_id, ti.task_id) for ti in tis)
@pytest.fixture
def dag_bag_multiple():