7
votes

Somme pour des rangées distinctes

Compte tenu des structures de table suivantes: xxx pré>

... et cette requête ... p> xxx pré>

Comment puis-je ajouter un Somme Code> du régions.population Code> Pour calculer la population du pays? Je dois utiliser seulement la valeur de chaque région une fois en résumé, mais le résultat des Nations Unies a plusieurs rangées pour chaque région (nombre de villes dans cette région). P>

Exemple de données: P>

SELECT c.id AS country_id,
    c.name AS country,
    COUNT(x.region_id) AS regions,
    SUM(x.population) AS population,
    SUM(x.cities) AS cities
FROM countries AS c
LEFT JOIN (
        SELECT r.country_id,
            r.id AS region_id,
            r.population AS population,
            COUNT(s.id) AS cities
        FROM regions AS r
        LEFT JOIN cities AS s ON s.region_id = r.id
        GROUP BY r.country_id, r.id, r.population
    ) AS x ON x.country_id = c.id
GROUP BY c.id, c.name


3 commentaires

Sûr de cette requête? Vous sélectionnez le nom de la ville comme «pays» et groupez par l'ID de la ville?


Avez-vous besoin de la population par région ou par pays?


Mon erreur. J'ai corrigé les alias. Je veux la population du pays.


7 Réponses :


2
votes

Utilisez JOIN EXTÉRIEUR DE GAUDÉ STRAND> au lieu de JOIN INTERNE STROND> Parce que si le pays n'a pas de régions, ce pays ne sera pas en résultat si vous utilisez Join Intérieur Strong >, même wat si des régions n'ont aucune villes que cela ne comptait pas en résultat.

Utilisez donc JOIN EXTÉRIEUR DE GAUCHE STROND> au lieu de JOIN INTERNE STRUT> ou JOIN STRUT>. p>

Essayez ceci: p> xxx pré>

cochez le SQL FIDDLE Demo strong> P>

Sortie forte> p>

| COUNTRY | REGIONS | POPULATION | CITIES |
|---------|---------|------------|--------|
|     usa |       3 |         16 |      4 |
| germany |       2 |          5 |      1 |


1 commentaires

Merci d'avoir discuté de la différence entre gauche et interne jointures. J'étais déjà au courant, mais cette information est bonne pour les futurs lecteurs.



4
votes

Que diriez-vous de quitter le reste et d'ajouter une autre jointure pour la population xxx

sqlfiddle Demo


0 commentaires

6
votes

Tout d'abord, le Autre message Vous référence n'est pas la même situation. Dans ce cas, les jointures sont comme [A -> B et A -> C], donc la moyenne pondérée (qui est ce que le calcul fait) est correct. Dans votre cas, les joines sont comme [A -> B -> C], vous avez donc besoin d'une approche différente.

La solution la plus simple qui vient à l'esprit tout de suite implique une sous-requête, mais pas un complexe: P >

SELECT 
    c.name AS country, 
    COUNT(r.id) AS regions, 
    SUM(s.city_count) AS cities,
    SUM(r.population) as population
FROM countries AS c
JOIN regions AS r ON r.country_id = c.id
JOIN 
    (select region_id, count(*) as city_count
    from cities 
    group by region_id) AS s
ON s.region_id = r.id
GROUP BY c.id


1 commentaires

Merci d'avoir illustré pourquoi cette autre solution ne s'applique pas à ma situation.



2
votes

J'ai test dans SQL avec cette requête pour la même table que vous fournissez ci-dessous xxx

et j'ai obtenu le résultat que vous voulez xxx


0 commentaires

3
votes

Pour commencer, vous devez savoir que la question et la solution mentionnée dans votre question sont un peu différentes de votre question et de sa solution. C'est pourquoi vous ne pouvez utiliser que rejoindre code> S sans sous-requêtes.

Tables: strong> p>

Pays: em> xxx pré>

régions: em> p> xxx pré>

villes: p >

=====================================================
|  country   |  regions   |   cities   | population |
=====================================================
| country 1  |     2      |     3      |     25     |
-----------------------------------------------------
| country 2  |     1      |     1      |     25     |
-----------------------------------------------------


0 commentaires

1
votes

Voici une autre façon de le faire, si vous ne voulez pas introduire / modifier un joindre ou un sous-requête xxx

http://sqlfiddle.com/#!2/3dd8ba/22/0


0 commentaires

1
votes

Votre problème est assez courant. Vous rejoignez toutes les tables qui ont quelque chose à voir avec les données que vous souhaitez voir, puis vous commencez à réfléchir à la manière d'accéder à ces données. En ce qui concerne des agrégations différentes comme dans votre cas, cela n'est pas facile à réaliser.

Do mieux rejoindre ce que vous êtes réellement intéressé. Dans votre cas: pays et région (agrégés) de la région / des données de la ville par pays. Cela empêche la requête directe directe et facile à entretenir. P>

select 
  c.name as country, 
  r.regions, 
  r.population,
  r.cities
from countries as c
join 
(
  select 
    country_id,
    count(*) as regions,
    sum(population) as population,
    sum((select count(*) from cities where cities.region_id = regions.id)) as cities
  from regions
  group by country_id
) as r on r.country_id = c.id;


0 commentaires