views:

823

answers:

5

I have a query that I need to execute that I do not know how to structure.

I have a table called Employees. I have another table called Company. There is a third table called Files. As you can imagine, a Company has Employees, and Employees have Files.

I need to list out all of the Employees in my database. The challenge is, I need to list the total number of Files in the same company as the Employee. I have tried variations on the following without any luck:

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

What am I doing wrong? Thank you!

A: 

How about:

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
Norman
bad idea to use pre ANSi-92 join (in the WHERE clause)
gbn
+4  A: 

Try this:

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
Kip
+1  A: 

A solution with no correlation in SELECT clause. Probably quicker...

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
gbn
+2  A: 

There are a lot of ways to get that. If the performance is a concern, this is more optimal according to estimated execution plan costs.

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
David Elizondo
yes, simplest. Better then mine.
gbn
but won't this just give the number of files that the given employee has? he wants the number of files for all employees in the same company as a given employee
Kip
Every employee belongs to a company, every file joined belongs to one employee. The query returns the employee information plus their number of files. You could filter it at the end to be WHERE e.Company = xxx.
David Elizondo
I'm with Kip - this just gives each employee and their file count. So Bob has 2 files and Jim has 5 for Company "A". The OP said they wanted file counts for the entire company the employee is in. So Bob and Jim should both read 5 as there are are 5 totals files for company "A".
WesleyJohnson
Whoops - typo. I meant Bob has 2 and Jim has 3. So 5 total. :)
WesleyJohnson
@WesleyJohnson, yes if the requirement is that (FileCount is the total files for the company of the employee, instead of the total files for the employee) then the @Kip approach is the one :)Let's see what the author of the question has to say.
David Elizondo
@David Elizondo: he seems to put it pretty clearly: "I need to list the total number of Files in the same company as the Employee"
Kip
A: 
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
van