2016-12-08 4 views
2

У меня есть база данных с, как показывает диаграмма (см рисунок ниже) enter image description hereSQL JOIN пункт условие

Моя задача состоит в том, чтобы показать общую стоимость заказов, обрабатываемых каждым сотрудников. У меня есть SQL заявление:

SELECT e.FirstName, 
     e.LastName, 
     SUM(od.Quantity * od.UnitPrice * (1-od.Discount)) 
FROM Orders AS o 
JOIN Employees AS e 
ON o.EmployeeID = e.EmployeeID 
JOIN [Order Details] AS od 
ON o.OrderID = od.OrderID 
GROUP BY e.FirstName,e.LastName 

У меня есть проблема с дальнейшими шагами. Мне нужно ограниченные результаты только для тех сотрудников, которые:

  • A) есть сотрудники, под ними
  • B) Не имею сотрудников под ними

Я знаю, что концерн поле ReportsTO в сотрудниках table, но я не знаю, как получить правильное предложение SQL. Я должен делать с «СУЩЕСТВУЮЩИМ» или самостоятельно присоединиться?

Thank you.

+0

Ваш ключ является первым словом в А и второе слово в б. его SQL-ключевое слово HAVING :) – logixologist

ответ

1

Да, просто используйте Exists.

Where Exists(Select 1 from Employees where ReportsTo = e.EmployeeId) 
+0

Это работает, если есть только 1 уровень отчетности. Если у вас несколько слоев людей (Сэм докладывает Джанет, который сообщает Амиту, который сообщает Тревору), этот запрос получает только заказы на Амит, когда вы запрашиваете отчеты Тревора. – HLGEM

+0

Но это все, что ему нужно. Ему не нужно было знать, есть ли несколько уровней. Ему просто нужно было знать, был ли у кого-то кто-то, кто их докладывал. –

+0

Если вам нужно перезагрузить уровни, вы можете использовать CTE и Union ALL –

1

Используйте автообъединение, чтобы попытаться найти кого-то подотчетный ему

SELECT e.FirstName, 
     e.LastName, 
     SUM(od.Quantity * od.UnitPrice * (1-od.Discount)) 
FROM Orders AS o 
INNER JOIN Employees AS e  
    ON o.EmployeeID = e.EmployeeID 
LEFT JOIN Employees as under -- self join 
    ON e.EmployeeID = under.ReportTo 
INNER JOIN [Order Details] AS od 
    ON o.OrderID = od.OrderID 
GROUP BY e.FirstName,e.LastName 

HAVING MAX(under.ReportTo) IS NULL  -- If doesnt find a match mean no one subordinate 
    -- MAX(under.ReportTo) IS NOT NULL -- mean have at least one subordinate 
+0

Спасибо за повтор, но, к сожалению, оператор работает только для: MAX (under.ReportTo) IS NOT NULL, MAX (under.ReportTo) IS NULL возвращается нет результатов. Инструкция @Dobbins ниже работает нормально, решая проблему с условием Exists – jadupl

+1

Я заменю объединение «LEFT» и «INNER», пожалуйста, проверьте еще раз. –

+0

Да, сейчас работает отлично. Спасибо. – jadupl

0

С автообъединением вы потенциально можете создавать дубликаты, которые были бы трудно отлаживать в связи с GROUP BY. EXISTS с коррелированным подзапросом в предложении WHERE будет так, как я бы это сделал.

SELECT * 
FROM Employees e 
WHERE EXISTS(
    SELECT 1 
    FROM Employees _e 
    WHERE _e.ReportsTo = e.EmployeeID) 

В запросе:

SELECT e.FirstName, 
     e.LastName, 
     SUM(od.Quantity * od.UnitPrice * (1-od.Discount)) 
FROM Orders AS o 
JOIN Employees AS e 
ON o.EmployeeID = e.EmployeeID 
JOIN [Order Details] AS od 
ON o.OrderID = od.OrderID 
WHERE /*NOT*/ EXISTS(
    SELECT 1 
    FROM Employees _e 
    WHERE _e.ReportsTo = e.EmployeeID) 
GROUP BY e.FirstName,e.LastName 
Смежные вопросы