Mysql
 sql >> Base de données >  >> RDS >> Mysql

sélectionner la requête et compter en fonction de la condition

Je ne vois aucune raison pour laquelle vous devriez utiliser une sous-requête. Je pense que vous pouvez simplement combiner fi_business et fi_business_subcategory à un seul facteur de tableau entre parenthèses.

SELECT
    c.id, 
    c.name,
    c.slug,
    sc.id,
    sc.name,
    sc.slug,
    COUNT(bsc.id) AS business_count
FROM
    fi_category c
LEFT JOIN
    fi_subcategory sc ON c.id = sc.category_id AND (sc.deleted_at IS NULL)
LEFT JOIN (
        fi_business b
    INNER JOIN
        fi_business_subcategory bsc ON b.id = bsc.business_id AND (bsc.deleted_at IS NULL)
    INNER JOIN
        fi_suburb su ON su.id = b.suburb_id AND su.city_id = 1
    ) ON sc.id = bsc.subcategory_id
WHERE 
    (c.deleted_at IS NULL) 
GROUP BY 
    c.id, sc.id

J'ai vérifié qu'il s'agit d'un SQL valide pour la structure de votre table. Je suppose qu'il y a de bonnes chances que cela donne le résultat souhaité, même si votre violon ne contient pas encore de données. Voir le manuel sur la syntaxe JOIN pour savoir où vous pouvez utiliser des parenthèses dans une jointure.

Vous pouvez également vous demander si vous avez vraiment besoin que toutes les jointures soient des jointures gauches. Écrire des choses en utilisant des jointures internes serait beaucoup plus facile.

Comme les jointures sont exécutées de gauche à droite, vous pouvez d'abord faire les jointures internes, suivies d'une séquence de droite rejoint. Cela évite les parenthèses :

SELECT
    c.id cat_id,
    c.name cat_name,
    c.slug cat_slug,
    sc.id sub_id,
    sc.name sub_name,
    sc.slug sub_slug,
    COUNT(bsc.id) AS business_count
FROM
    fi_business b
INNER JOIN
    fi_business_subcategory bsc ON b.id = bsc.business_id
    AND (b.deleted_at IS NULL) AND (bsc.deleted_at IS NULL)
INNER JOIN
    fi_suburb su ON su.id = b.suburb_id AND su.city_id = 1
RIGHT JOIN
    fi_subcategory sc ON sc.id = bsc.subcategory_id
RIGHT JOIN
    fi_category c ON c.id = sc.category_id AND (sc.deleted_at IS NULL)
WHERE
    (c.deleted_at IS NULL)
GROUP BY
    c.id, sc.id