Pregunta

thanks in advnace for reading this. I'm not really good with SQL so please pardon any stupid mistake...

Here is the deal, I have four tables (i'm only going to give the basic fields, and dependencies between tables, for the sake of simplicity):

  1. Company: companyId, companyName
  2. User: userId, userName
  3. Project: projectId, projectUserId, projectCompanyId, projectDate
  4. Study: studyProjectId

The dependencies are like so:

  • A project is for a client (projectUserId) and carried out by a company (projectCompanyId)
  • There can be many studies for the same project, but each study is for one project (studyProjectId)

Here is the kind of request I'd like to write, but it doesn't work right now:

SELECT
    project.projectId,
    company.companyName,
    user.userName,
    COUNT( study.studyId ) AS numberStudies
FROM project, company, user, study
WHERE company.companyId = project.projectCompanyId,
AND user.userId = project.projectUserId,
AND study.studyProjectId = project.projectId
ORDER BY company.companyId, user.userId, project.projectDate;

It returns one record for which numberStudies equals the total number of studies. If I remove the COUNT from the SELECT, then I get the type of result I want, but without the column numberStudies (of course). Hoping you understand what I'm trying to get, what am I doing wrong here?

Thanks again in advance :)

EDIT: If possible, I'd like the request to show records even when numberStudies is 0.

¿Fue útil?

Solución

As in the comments, you need a GROUP BY clause when you want to have aggregate results (like it seems you want: "Number of Studies per project, company and user"). So, the first thing to do is add:

GROUP BY project.projectId, company.companyName, user.userName

Notice that the three columns are exactly the three that you have (unaggregated) in the SELECT list.

SELECT
    project.projectId,
    company.companyName,
    user.userName,
    COUNT(study.studyId) AS numberStudies
FROM project, company, user, study
WHERE company.companyId = project.projectCompanyId,
  AND user.userId = project.projectUserId,
  AND study.studyProjectId = project.projectId
GROUP BY project.projectId, company.companyName, user.userName
ORDER BY company.companyId, user.userId, project.projectDate ;

This will show what you want but there are still a few issues:

  • First, you are using the old (SQL-89) syntax of implicit joins with the conditions in the WHERE clause. This syntax is not deprecated but the new (well, 20 years old SQL-92) syntax with the JOIN keyword has several advantages.
  • We can add aliases for the tables for readability.
  • There may be two companies or users with same name so we should group by their IDs, not only their names.
  • One advantage of explicit JOIN syntax is that it's easy to have results when there are no rows to join (as you want to show when there is no studies for a project). Just LEFT JOIN the study table.

So, the query becomes:

    SELECT
        p.projectId,
        c.companyName,
        u.userName,
        COUNT(s.studyId) AS numberStudies
    FROM 
        project AS p
      JOIN 
        company AS c  ON c.companyId = p.projectCompanyId
      JOIN 
        user AS u     ON u.userId = p.projectUserId
      LEFT JOIN 
        study AS s    ON s.studyProjectId = p.projectId
    GROUP BY 
        c.companyId,
        u.userId,
        p.projectId, 
        c.companyName,  u.userName
    ORDER BY 
        c.companyId, 
        u.userId, 
        p.projectDate ;

Otros consejos

you probably need a LEFT JOIN between study and project

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top