开发者

SQL - Oracle Database 10g Group By Queries

I am currently having an issue with the GROUP BY statements in Oracle Database 10g with my database.

I have four tables in this database - Advertisements, Staff, StaffGrade and StaffOnAd. What I'm trying to query is for advertisements with more than three staff members working on them, I want to list that advert title and the number of staff members who have a payment grade greater than 2.

Below is my开发者_Python百科 attempt:

SELECT Camp.Title 
FROM Campaign Camp
LEFT JOIN WorksOn Wo ON Camp.Title = Wo.Title
LEFT JOIN Staff Stf ON Wo.StaffNo = Stf.StaffNo
LEFT JOIN StaffOnGrade StfOGrde ON Stf.StaffNo = StfOGrde.StaffNo
WHERE StfOGrde.Grade > 2 AND Camp.Title IN (SELECT Camp2.Title FROM Campaign Camp2
LEFT JOIN WorksOn Wo2 ON Camp2.Title = Wo2.Title
WHERE COUNT(Camp2.Title) > 3)
GROUP BY Camp.Title

The error I received with the above is: ORA-00934: group function is not allowed here

I searched around and basically that error tells me that the way I'm grouping is wrong but I have no idea why that is. Also I was just wondering was is the correct way to format the above code?

Any help is appreciated.

NOTE: Just some more information regarding the tables below

  • Advertisements basically has fields regarding air date etc.
  • Staff has their personal details recorded.
  • StaffGrade shows what payment grade a staff member is on.
  • StaffOnAd shows what staff member works on what advertisement by the title of the ad.

EDIT 1: Tried the following after comments:

SELECT Camp.Title 
FROM Campaign Camp
LEFT JOIN WorksOn Wo ON Camp.Title = Wo.Title
LEFT JOIN Staff Stf ON Wo.StaffNo = Stf.StaffNo
LEFT JOIN StaffOnGrade StfOGrde ON Stf.StaffNo = StfOGrde.StaffNo
WHERE StfOGrde.Grade > 2 AND Camp.Title IN (SELECT Camp2.Title FROM Campaign Camp2
LEFT JOIN WorksOn Wo2 ON Camp2.Title = Wo2.Title
HAVING COUNT(Camp2.Title) > 3)
GROUP BY Camp.Title

However, I received a new error: ORA-00937: not a single-group group function

EDIT 2:

SELECT Camp.Title 
FROM Campaign Camp
  LEFT JOIN WorksOn Wo ON Camp.Title = Wo.Title
  LEFT JOIN Staff Stf ON Wo.StaffNo = Stf.StaffNo
  LEFT JOIN StaffOnGrade StfOGrde ON Stf.StaffNo = StfOGrde.StaffNo
WHERE StfOGrde.Grade > 2 
  AND Camp.Title IN 
      ( SELECT Camp2.Title 
        FROM Campaign Camp2
          LEFT JOIN WorksOn Wo2 
            ON Camp2.Title = Wo2.Title
        GROUP BY Camp2.Title
        HAVING COUNT(Camp2.Title) > 3
      )
GROUP BY Camp.Title

No errors in this revised query. However, the only results that are being displayed is titles of the advertisement where I also need the amount of staff members working on that advert with grade payment greater than 2. I just assumed that the last group by statement would fix this issue, but I don't think its necessary.


First of all... Always, when you put into your select some condition in the left joined table, you'll have an inner join. Based in your requirements:

  • List with advert title and number of staff members who have a payment grade grater than 2
  • Advertisements with more than 3 Staff members

I would do something like this:

    SELECT title, SumGradeGreaterThan2
      FROM (SELECT   camp.title, COUNT (*) AS StaffMembers,
                     SUM (CASE
                             WHEN stfogrde.grade > 2
                                THEN 1
                             ELSE 0
                          END) AS SumGradeGreaterThan2
                FROM  Campaign Camp
                LEFT JOIN WorksOn Wo ON Camp.Title = Wo.Title
                LEFT JOIN Staff Stf ON Wo.StaffNo = Stf.StaffNo
                LEFT JOIN StaffOnGrade StfOGrde ON Stf.StaffNo = StfOGrde.StaffNo
            GROUP BY camp.title)
     WHERE StaffMembers > 3


You can't use aggregate functions in a where clause. Change this:

WHERE COUNT(Camp2.Title) > 3)

to this:

HAVING COUNT(Camp2.Title) > 3)


I think you need:

SELECT Camp.Title 
FROM Campaign Camp
  LEFT JOIN WorksOn Wo ON Camp.Title = Wo.Title
  LEFT JOIN Staff Stf ON Wo.StaffNo = Stf.StaffNo
  LEFT JOIN StaffOnGrade StfOGrde ON Stf.StaffNo = StfOGrde.StaffNo
WHERE StfOGrde.Grade > 2 
  AND Camp.Title IN 
      ( SELECT Camp2.Title 
        FROM Campaign Camp2
          LEFT JOIN WorksOn Wo2 
            ON Camp2.Title = Wo2.Title
        GROUP BY Camp2.Title              --- the GROUP BY was missing
        HAVING COUNT(Camp2.Title) > 3     --- HAVING, not WHERE
      )
GROUP BY Camp.Title                       --- is this needed? (or was misplaced?)
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜