how to select count in oracle - oracle

enter image description here
how to count salary where job_title ?
I tried with coding like this, but the result error
this my code
select a.job_id,a.job_title,avg(b.salary) gaji_rata_rata
from jobs a, employees b where a.job_id=b.job_id order by job_id;

You need a group when using aggregation function
select a.job_id,a.job_title,avg(b.salary) gaji_rata_rata
from jobs a, employees b
where a.job_id=b.job_id
group by a.job_id,a.job_title
order by job_id;

Related

Joining 4 tables using nested queries Oracle

I am using nested queries to achieve this:
Basically, I have this:
employee table:
employee_id, locale
audience table
employee_id
country table
country_name,country_code
country_language
country_code, geo
I need this: employee_id,audience_id,country_name,locale from these tables that come under "APAC" geo:
I have this query:
SELECT employee_id
FROM audience
WHERE employee_id IN
(SELECT employee_id
FROM employee
WHERE LOCALE IN
(SELECT LOCALE
FROM COUNTRY_LANGUAGE
WHERE COUNTRY_CODE IN
(SELECT COUNTRY_CODE
FROM COUNTRY
WHERE GEO='apac')
)
)
ORDER BY employee_id);
This is throwing this error: "SQL command not properly ended"
Also, will this query produce right results if run properly? If not, can u suggest something else?
Used this as joins. Did not return anything:
select a.employee_id,
a.locale,
b.audience_id,
c.LOCALE_CODE,
d.COUNTRY_NAME
from employee a,
audience b,
country_language c,
country d
where
a.employee_id=b.employee_ID
and d.geo='apac'
and d.country_code=c.country_code
and a.locale=c.LOCALE_CODE;
You can try to use UNION SELECT

How to use GROUP BY clause with COUNT(*)

I have two tables on Oracle database, one is named departments_table and the other is locations_table. The departments.table has dep_id, dep_name, location_id, staff_id, employer_id. The locations table consists of location_id, city_id, streetname_id and postcode_id. How do I calculate the number of departments that each location has?
This is the code below is what I have tried to replicate but have been unsuccessful. The error message below that is what shows once the code has submitted.
SELECT dep_name, location_id,
COUNT(*)
FROM departments_table
WHERE location_id => 1
GROUP BY dep_name;
The results of this is an error, " not a single group function "
If you want to count how many departments are in each location, then you must group by location, not by department name, right? Let's start with that.
Then, you don't need ANYTHING about the individual departments in the output of the query, do you? You just need the location id and the count of departments.
select location_id, count(*) as cnt
from departments_table
group by location_id
;
This does most of the work. You may want to add the location name (city, address, etc.), which is/are stored elsewhere - in the locations_table. So you will need a join. And there may be locations in that table that are not, in fact, the location of any department (their id doesn't appear in the departments_table at all). If so, you would need an OUTER join. Also for those departments you probably want to show a count of 0 (rather than null) - you can "fix" that with the nvl() function. So you will end up with something like
select l.*, nvl(g.cnt, 0) as department_count
from locations_table l
left outer join
( select location_id, count(*) as cnt
from departments_table
group by location_id
) g
on l.location_id = g.location_id
;
SELECT l.location_id, l.city, COUNT(d.DEPARTMENT_ID)
FROM OEHR_LOCATIONS l, OEHR_DEPARTMENTS d WHERE l.location_id = d.location_id
GROUP BY l.location_id, l.city ORDER BY l.city;
This method works. I created aliases and made minor changes. OEHR stands for the table names so ignore that.

Using PARTITION BY and the order is messing up when I insert. Why?

I wanted to order the employees by time they started an assignment, so that the results would look like this:
So I am using a query similar to:
SELECT a.employeename, b.assignmenttime, ROW_NUMBER() OVER (PARTITION BY a.employeename order by b.assignmenttime) sequence
FROM emplyee a, tasks b
WHERE a.id = b.id
ORDER BY a.employeename, b.assignmenttime
This is inside a procedure and every time the procedure gets called I want the results to be written to a table.
So I have:
INSERT INTO MyTable (Emp,Time,Sequence)
SELECT a.employeename, b.assignmenttime, ROW_NUMBER() OVER (PARTITION BY a.employeename order by b.assignmenttime) sequence
FROM emplyee a, tasks b
WHERE a.id = b.id
ORDER BY a.employeename, b.assignmenttime;
commit;
This is all fine except when the records are written to the table the order gets messed up sometimes and I end up with
As you can see the sequence is not in order. A normal query always returns the records in the right order but why when I call the procedure the records get written out of order in the table? What do I have to do to fix this? Using oracle 10g

Oracle stored procedure - gradual building of of out variable

I'm sorry for my strange title, but I don't know what exactly I'm looking for. The task is quite simple. I have the table of competitions. Another table groups. In every group there are several contestants. In the last table are stored the results of contestants. The task is to get the first three of the contestants of every group.
So I have to loop through the groups, get the first three contestants (according to achieved points) of every group and append them into some variable.
Here is the pseudocode:
CREATE OR REPLACE PROCEDURE get_first_three_of_all(contestants OUT SOME_TYPE) AS
CURSOR groups SELECT...
BEGIN
FOR group IN groups LOOP
APPEND(contestants, get_first_three_of_one_group(group.id))
END LOOP;
END;
I have no idea, how to solve this task. I even don't know what should I look for. Would you be so kind and help me, please? Thanks.
Edited: simplified structure of my tables:
Competition: competition_id
Contestant: contestant_id
GroupContestant: contestant_group_id, competition_d, group_number, contestant_id
Result: contestant_group_id, juror, points
Select to get data of one group (group number YYY) is here:
SELECT * FROM (
SELECT res.contestant_group_id, SUM(res.points) AS points
FROM Result res
WHERE res.couple_group_id IN (SELECT couple_group_id
FROM GroupContestant
WHERE competition_id = XXX
AND group_number = YYY)
GROUP BY res.contestant_group_id
ORDER BY points DESC
)
WHERE ROWNUM <= 3;
Analytic functions to the rescue. To select top 3 results for each group, each competition:
SELECT * FROM (
SELECT grp.competition_id, grp.group_number, res.contestant_group_id, res.points,
row_number() over (partition by grp.competition_id, grp.group_number
order by res.points desc) rn
FROM (SELECT contestant_group_id, SUM(points) AS points
FROM Result
GROUP BY contestant_group_id) res
JOIN GroupContestant grp ON (grp.contestant_group_id = res.contestant_group_id)
)
WHERE rn <= 3;
Pay attention to how you resolve ties (consider using rank or dense_rank instead of row_number).
You can use RANK() analytic function to achieve the goal:
select *
from (select group_num,
points,
rank() over(partition by group_num order by points desc) rank
from results
inner join group_contestant
using (contestant_group_id))
where rank <= 3
order by group_num, points desc;
Here is SQLFiddle to play with.

Display only the largest count in a group by statment

I'm trying to display only the largest group in this group by statement;
SELECT COUNT(type) AS booking, type FROM booking b, room r WHERE r.rno = b.rno AND r.hno = b.hno GROUP BY type;
I modified it so we get this query response now you can see group double is larger then family.
BOOKING TYPE
5 double
2 family
I know there is a HAVING keyword you can add in order display only a count compared to a number so I could do COUNT(type) HAVING > 2 or similar but that's not very dynamic and that would only work in this instance because I know the two amounts.
ORDER BY COUNT(type) DESC LIMIT 1
There isn't a having statement that does this. But you can use rownum with a subquery:
select t.*
from (SELECT COUNT(type) AS booking, type
FROM booking b join
room r
on r.rno = b.rno AND r.hno = b.hno
GROUP BY type
order by count(type) desc
) t
where rownum = 1;
Just order your query..
order by booking desc
regards
TRY this
SELECT COUNT(type) AS booking, type FROM booking b, room r WHERE r.rno = b.rno AND r.hno = b.hno ORDER BY type DESC LIMIT 1

Resources