2016-03-09 2 views
1

Косидер следующей структуры для населения.Суммарные иерархические значения в таблице для континентов, стран и штатов

Asia(100+50+150=300) 
    > China (20+80=100) 
     > China_StateA (20) 
     > China_StateB (80) 
    > KSA (10+40=50) 
     > KSA_StateA (10) 
     > KSA_StateB (40) 
    > India (70+80=150) 
     > India_StateA (70) 
     > India_StateB (80) 


Europe(50+15=65) 
    > England (50) 
     > England_StateA (20) 
     > England_StateB (30) 
    > Ireland (5+10=15) 
     > Ireland_StateA (5) 
     > Ireland_StateB (10) 

Если я иметь такую ​​же структуру, в одной таблице базы данных, как следующий

Id Type Name ParentId Population 
1 Continent Asia 0 
2 Country China 1 
3 State China_StateA 2 20 
4 State China_StateB 2 80 
5 Country KSA 1 
6 State KSA_StateA 5 10 
7 State KSA_StateB 5 40 
8 Country India 1 
9 State India_StateA 8 70 
10 State India_StateB 8 80 
11 Continent Europe 0 
12 Country England 11 
13 State England_StateA 12 20 
14 State England_StateB 12 30 
15 Country Ireland 11 
16 State Ireland_StateA 15 5 
17 State Ireland_StateB 15 10 

Тогда как я могу написать SQL запрос, который будет возвращать население на каждом уровне. т. е. подведет население штатов, чтобы найти население страны. Аналогичным образом суммирует население стран, чтобы найти население континентов.

+1

Я думаю, вы связать «государство» записи с «Страна» записей по имени. Но, как вы связываете континент со странами? Выбрав поле ID? Я думаю, что самый простой способ добиться того, что вы хотите, - это функция или хранимая процедура и итерация по курсору: https://msdn.microsoft.com/es-es/library/ms180169(v=sql.120).aspx – Rumpelstinsk

+1

Есть ли способ узнать, в какой стране принадлежит какой континент и какое государство принадлежит какой стране? Я имею в виду, что некоторые из нас знают, что Индия находится в Азии, но база данных этого не делает. – Nitish

+0

Обновленный комментарий: Используйте [иерархические запросы] (https://msdn.microsoft.com/en-in/library/bb677191.aspx) – Nitish

ответ

1

Если вы хотите, чтобы подвести после континентов, один подход просто добавить столбец континент

Сумма после континента затем

SELECT sum(Population) FROM yourTable GROUP BY continent. 

Другой подход заключается в нечто подобное с закодированного списка

Sum после континентов

Просто используйте sum и group by с REGEXP_SUBSTR с входом и жестко запрограммированным списком. В моем случае Германия, Англия должна представлять Европу.

SELECT sum(Population) FROM yourTable GROUP BY REGEXP_SUBSTR('Name','(.*)_?') IN ('England', 'Germany') 
+0

Это решение даст ему резюме для стран, но не для континентов. – Rumpelstinsk

+0

@ Румпельстинск Большое спасибо за уведомление. Просто рано утром. Я обновил свой ответ. – Kordi

0

Решение Kordi поможет вам, если вы хотите получить данные для стран и континентов в отдельных видах или в определенных странах. Но если вы хотите видеть все в одном представлении, и у вас есть только 2 уровня в вашей иерархии, вы можете использовать этот запрос.

SELECT parent.Id 
    parent.Name, 
    parent.ParentId 
    SUM(childs.Population) 
FROM mytable parent 
    INNER JOIN mytable childs ON parent.Id = childs.ParentId 
WHERE parent.Type = 'Continent' 
GroupBy parent.Id, parent.Name, parent.ParentId 

UNION 

SELECT parent.Id 
    parent.Name, 
    parent.ParentId 
    SUM(childs.Population) 
FROM mytable parent 
    INNER JOIN mytable childs ON parent.Id = childs.ParentId 
WHERE parent.Type = 'Country' 
GroupBy parent.Id, parent.Name, parent.ParentId 

ПРИМЕЧАНИЕ: Если у вас есть более 2 уровней иерархии, 2 обходные пути для этого запроса являются, используя XML PATH или курсоры внутри процедуры магазина или функции.

1

Вы можете сделать это с помощью КТР

WITH CTE_TMP 
AS 
(
    SELECT Id,[Type],Name,ParentId,[Population] 
    FROM MyTable 
    WHERE [Type] = 'State' 
    UNION ALL 
    SELECT M.Id,M.[Type],M.Name,M.ParentId,ISNULL(C.[Population],0) 
    FROM MyTable M 
    INNER JOIN CTE_TMP C ON M.Id = C.ParentId 
) 
SELECT Id,[Type],Name,ParentId,SUM([Population]) AS [Population] 
FROM CTE_TMP 
GROUP BY Id,[Type],Name,ParentId 
ORDER BY id 
+0

Ницца. Одна небольшая ошибка: у вас есть паразитный ';' в самом начале вашего заявления. –

+0

Спасибо, Фрэнк Шмитт –

Смежные вопросы