SQL Server 2005 - 嵌套递归查询:(

时间:2009-10-27 20:08:18

标签: sql sql-server sql-server-2005 correlated-subquery

我有一个我需要执行的查询,我不知道如何构建。

我有一张名为Employees的表。我还有另一张叫做公司的桌子。还有第三个名为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 个答案:

答案 0 :(得分:5)

试试这个:

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

答案 1 :(得分:2)

有很多方法可以做到这一点。如果表现是一个问题,根据估计的执行计划成本,这是更优化的。

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

答案 2 :(得分:1)

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

答案 3 :(得分:0)

怎么样:

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

答案 4 :(得分:0)

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

答案 5 :(得分:0)

以下语句使用递归连接来迭代管理管理其他员工的其他员工的员工....等我们的结构有点复杂,因为管理结构基于角色,实际上允许员工拥有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