2009-04-09 3 views
2

Дайте следующую простую структуру таблицы:Несколько Граф в SQL Query

Departments 
PK - DeptID DeptName 
-------------------------- 
1    Department 1 
2    Department 2 
3    Department 3 
4    Department 4 

Groups 
PK - GroupdID DeptID 
-------------------------- 
1    1 
2    1 
3    3 
4    4 
5    2 
6    3 
7    1 
8    3 

Inventory 
PK - ItemID GroupID 
-------------------------- 
1    2 
2    3 
3    8 
4    1 
5    4 
6    5 
7    1 
8    2 
9    2 
10    3 
11    7 

Есть ли способ без использования подзапросов (что легко), где я мог бы получить список отделов, граф групп в каждом отделе и подсчет запасов в каждом отделе?

Результат:

DeptID DeptName   GroupCount  ItemCount 
----------------------------------------------------- 
1   Department 1  3    6 
2   Department 2  1    1 
3   Department 1  3    3 
4   Department 4  1    1  

Моя кишка говорит мне, что это всего лишь простой вопрос получения GROUP BY заявления исправить, но до сих пор я рисую пустой. Если это требует использования подзапросов, это не проблема. Я просто хотел подтвердить для будущей ссылки.

ПРИМЕЧАНИЕ: Использование SQL Server 2000 для этой конкретной проблемы

+0

@Lieven: спасибо за этот тег редактирования. Я так привык работать в 2005 году, что тегирование стало инстинктом. – TheTXI

+0

@TheTXI: не упоминайте об этом. Кстати, я считаю, что количество групп и предметов отдела 2 должно быть 1 ?! –

+0

Почему количество групп 0 для отдела 2? – Quassnoi

ответ

11
SELECT d.deptID, 
     COUNT(DISTINCT g.GroupID) AS Groups, 
     COUNT(DISTINCT i.ItemID) AS Items 
FROM Departments d 
LEFT JOIN 
     Groups g 
ON  g.deptID = d.deptID 
LEFT JOIN 
     Items i 
ON  i.GroupID = g.GroupID 
GROUP BY 
     d.deptID 

Результаты, полученные являются:

deptID Groups Items 
----- ------ ----- 
1  3  6 
2  1  1 
3  3  3 
4  1  1 

Это также будет производить правильные 0 «S для Departments, которые не имеют Groups или имеют только Groups без Items.

+0

Очень приятно. В следующий раз я подожду, пока SQL Express не завершит установку перед ответом. –

+0

Картезианское соединение здесь почти невозможно. Скорее всего, это будет HASH JOIN между группами и отделами, затем HASH JOIN между набором результатов и элементами.Набор результатов будет иметь точно такое же количество строк, что и департаменты, при условии, что GroupID и DeptID являются первичными ключами. – Quassnoi

+0

Да, мое мышление было испорчено этим - я думал, что предметы соединялись с Департаментами, а не группами. Doh. –

0

К сожалению, я не сидел перед моим SQL Server. Вот вам первая попытка. Я мог бы не правильно понять желаемый результат, но, возможно, вы можете использовать это как отправную точку?

SELECT 
    Department.DeptId, 
    Department.DeptName, 
    Group.GroupId, 
    COUNT (Inventory.GroupId) as TotalItems 
FROM 
    Department 
    INNER JOIN Groups 
    On (Department.DeptId = Groups.DeptId) 
    INNER JOIN Inventory 
    On (Inventory.GroupId = Groups.GroupId) 
GROUP BY 
    Department.DeptId, 
    Department.DeptName 
    Group.GroupId, 
    Inventory.GroupId 
1

Ниже представлен хотя бы один из способов получения результатов.

SELECT d.DeptID, d.DeptName, ISNULL(g.Groups, 0), ISNULL(t.TotalItems, 0) 
FROM 
    Departments d 
    LEFT OUTER JOIN (
    SELECT d.DeptID, Groups = COUNT(*) 
    FROM Departments d 
     INNER JOIN Groups g ON g.DeptID = d.DeptID 
    GROUP BY d.DeptID 
) g ON g.DeptID = d.DeptID 
    LEFT OUTER JOIN (
    SELECT d.DeptID, TotalItems = COUNT(*) 
    FROM Departments d 
     INNER JOIN Groups g ON g.DeptID = d.DeptID 
     INNER JOIN Inventory i ON i.GroupID = g.GroupID 
    GROUP BY d.DeptID 
) t ON t.DeptID = d.DeptID 
+0

В примере данных ваш запрос будет работать, но он выберет примечание для отдела, у которого нет групп. – Quassnoi

+0

@Quassnoi: ответ скорректирован с учетом вашего замечания. –

1

Вот моя попытка ...

declare @Depatments table 
(
DeptID int 
,DeptName varchar(15) 
) 

declare @Groups table 
(
GroupID int 
,DeptID int 
) 

declare @Inventory table 
(
ItemID int 
,GroupID int 
) 

INSERT INTO @Depatments VALUES (1,'Department 1') 
INSERT INTO @Depatments VALUES (2,'Department 2') 
INSERT INTO @Depatments VALUES (3,'Department 3') 
INSERT INTO @Depatments VALUES (4,'Department 4') 

INSERT INTO @Groups VALUES (1,1) 
INSERT INTO @Groups VALUES (2,1) 
INSERT INTO @Groups VALUES (3,3) 
INSERT INTO @Groups VALUES (4,4) 
INSERT INTO @Groups VALUES (5,2) 
INSERT INTO @Groups VALUES (6,3) 
INSERT INTO @Groups VALUES (7,1) 
INSERT INTO @Groups VALUES (8,3) 

INSERT INTO @Inventory VALUES (1 ,2) 
INSERT INTO @Inventory VALUES (2 ,3) 
INSERT INTO @Inventory VALUES (3 ,8) 
INSERT INTO @Inventory VALUES (4 ,1) 
INSERT INTO @Inventory VALUES (5 ,4) 
INSERT INTO @Inventory VALUES (6 ,5) 
INSERT INTO @Inventory VALUES (7 ,1) 
INSERT INTO @Inventory VALUES (8 ,2) 
INSERT INTO @Inventory VALUES (9 ,2) 
INSERT INTO @Inventory VALUES (10,3) 
INSERT INTO @Inventory VALUES (11,7) 


--works with derived tables 
SELECT 
    d.DeptName,dt_g.CountOf AS GroupCount, dt_i.CountOf AS InventotyCount 
    FROM @Depatments d 
     LEFT OUTER JOIN (SELECT 
          COUNT(*) AS CountOf,DeptID 
          FROM @Groups 
          GROUP BY DeptID 
         ) dt_g ON d.DeptID=dt_g.DeptID 
     LEFT OUTER JOIN (SELECT 
          COUNT(*) AS CountOf,g.DeptID 
          FROM @Groups    g 
           INNER JOIN @Inventory i ON g.GroupID=i.GroupID 
          GROUP BY DeptID 
         ) dt_i ON d.DeptID=dt_i.DeptID 
+0

Использование ISNULL вернет 1 вместо 0 для департаментов, у которых нет групп. Исключение NULL предназначено здесь. – Quassnoi

+0

Я изначально пытался сделать это с помощью SUM (CASE WHEN NULL THEN 0 ELSE 1 END), но оказалось, что просто COUNT проще, и предупреждение на самом деле не повредит :) – Quassnoi

+0

@Quassnoi, правильно! Я забыл о том, как COUNT() вокруг него будет считать 0! –

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

  • Нет связанных вопросов^_^