depends_on option: it will start services in dependency order, but won't wait for the dependent service to be ready.
wait script: wait-for-it recommended by Docker's Controlling startup order in Compose, which checks the database port and waits. Unluckily, this doesn't help. The reason is that the port will be available right after the database container starts, while it doesn't mean that the database connection is ready. Just forget about nc -v -n -z -w1 $HOST $PORT.
Database logs: the readiness status of MySQL is written in its logs, could be read by grep 'ready for connections'. While keep in mind, the logs are only accessible with inside the MySQL container, or from the host machine, but not from the SonarQube container. Maybe you wanna try to persist MySQL logs to the host directory, and then mount it to the SonarQube container, so that it could be gotten from there. However, mounting the same host directory to multiple running containers is not really a good idea.
Database command: how about simply executing mysql -e "select 1" to check the database availability? Yep, but wait a second, the SonarQube container doesn't have mysql client installed, and we have no control of the official SonarQube docker image.
Web Server: yet another hack - setting up a minimal (one-liner) web server at the MySQL container, responds with the database status, just like while true; do echo -e 'HTTP/1.1 200 OK\n\n $(db_status)' | nc -l -p 9999; done. Unfortunately again, netcat is not installed by the MySQL container.
HEALTHCHECK instruction: new feature since Docker v1.12, but not for docker-compose yet. Usage: HEALTHCHECK [OPTIONS] CMD command. Still, you have to write the command on your own, to tell docker what to check.
JDBC: finally, here comes an easy solution - creating a java file, which has some code utilizing JDBC to check the database availability (Java environment and JDBC jar are both available within the SonarQube container). Just override the entrypoint of the SonarQube container, first check the database availability via this java code, then run the default entrypoint shell script when the database is ready. Pretty slick and it works great!