SQL Server 2005 - вложенный рекурсивный запрос :( - PullRequest
2 голосов
/ 27 октября 2009

У меня есть запрос, который мне нужно выполнить, и я не знаю, как его структурировать.

У меня есть таблица под названием «Сотрудники». У меня есть еще один стол под названием Company. Есть третья таблица, которая называется Files. Как вы можете себе представить, в компании есть сотрудники, а у сотрудников есть файлы.

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

SELECT
  e.FirstName,
  e.LastName,
  e.Company,
  (SELECT COUNT(*) FROM Files f WHERE f.EmployeeID IN (SELECT [ID] FROM Employees e2 WHERE e2.CompanyID=e.CompanyID)) as 'FileCount'
FROM
  Employees e

Что я делаю не так? Спасибо!

Ответы [ 6 ]

5 голосов
/ 27 октября 2009

Попробуйте это:

SELECT
  e.FirstName,
  e.LastName,
  e.Company,
  (
    SELECT COUNT(*)
    FROM Files f
    JOIN Employees e2 ON f.EmployeeID = e2.id
    WHERE e2.CompanyID = e.CompanyID
  ) as 'FileCount'
FROM
  Employees e
2 голосов
/ 27 октября 2009

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

SELECT
  e.FirstName,
  e.LastName,
  e.Company,
  COUNT(f.FileId)
FROM
  Employees e
  INNER JOIN Files f ON e.EmployeeID = f.EmployeeID
GROUP BY
  e.FirstName,
  e.LastName,
  e.Company
1 голос
/ 27 октября 2009

Решение без корреляции в предложении SELECT. Наверное, быстрее ...

SELECT
    e.FirstName,
    e.LastName,
    e.Company,
    foo.FileCount
FROM
    Employees e
    JOIN
    (
    SELECT
       COUNT(*) AS FileCount, --OR COUNT(DISTINCT something) ?
       e2.Company, f.EmployeeID
    FROM
       Files f JOIN Employees e2 ON f.EmployeeID = e2.id
    GROUP BY
       e2.Company, f.EmployeeID
    ) foo ON e.Company = foo.Company AND e.id = foo.EmployeeID
0 голосов
/ 11 ноября 2013

В следующем утверждении используются рекурсивные объединения для итерации сотрудников, которые управляют другими сотрудниками, которые управляют другими сотрудниками ... и т. Д. Наша структура немного запутана, поскольку структура управления основана на ролях, что фактически позволяет сотруднику иметь более 1 менеджер. Вы можете добавить ссылку на файлы в этой рекурсии.

WITH Manager as
(SELECT c.Forenames + ' ' + c.Surname as Employee,
  c2.Forenames + ' ' + c2.Surname AS Manages,
  c.accountid AS AccountID, c.[Status] AS [Status]
  FROM [intranet].[dbo].[tblContact] c
  LEFT JOIN tblContactPost cp ON cp.contactid = c.contactid
  LEFT JOIN tblPost p ON p.ParentRoleId = cp.RoleID AND p.ParentPostArea = cp.PostArea AND p.ParentPostNo = cp.PostNo
  INNER JOIN tblContactPost cp2 ON cp2.RoleId = p.RoleId AND cp2.PostArea = p.PostArea AND cp2.PostNo = p.PostNo
  INNER JOIN tblContact c2 ON c2.ContactID = cp2.ContactId
  )
  ,jn AS
  (SELECT Employee, Manages
    FROM Manager
    Where AccountID = 'ad\lgardner' AND [Status] = 'A'
    UNION ALL
    SELECT c.Employee, c.Manages
    FROM jn as p JOIN Manager AS c
    ON c.Employee = p.Manages
    )
SELECT jn.Employee, jn.Manages
From jn
Order BY 1
0 голосов
/ 28 октября 2009
WITH FilesPerCompany (CompanyID, NumberOfFiles)
AS (SELECT      c.ID AS CompanyID,
                COUNT(*) AS NumberOfFiles
    FROM        Companies c
    INNER JOIN  Employees e ON  c.ID = e.CompanyID
    INNER JOIN  Files f     ON  e.ID = f.EmployeeID
    GROUP BY    c.ID
)

SELECT      e.FirstName,
            e.LastName,
            e.Company,
            COALESCE(s.NumberOfFiles, 0) AS NumberOfFilesPerCompany
FROM        Employees e
LEFT JOIN   FilesPerCompany s
        ON  s.CompanyID = e.CompanyID
0 голосов
/ 27 октября 2009

Как насчет:

SELECT
   e.FirstName,
   e.LastName,
   e.Company,
   select count(*) from Files f, Employees e where f.EmployeeID=e.EmployeeID and e.CompanyID=emp.CompanyID
FROM
  Employees emp
...