Using Aggregate Functions in sql - sql

Hoe can I do following thing without using a VIEW from one Query.
!--CREATE THE VIEW
CREATE OR REPLACE VIEW BDGTMGR
AS
SELECT MANAGERID,SUM(BUDGET) AS BDGT FROM
N_DEPT GROUP BY MANAGERID ;
!-- THEN GET RESULT FROM THE VIEW
SELECT MANAGERID FROM BDGTMGR WHERE BDGT = (select MAX(BDGT) FROM BDGTMGR);
Here N_DEPT is may original Table which has columns named DID, MANAGERID and BUDGET.
I want to get MANAGERID who controls Maximum Budget. A Manager can control more than one Department. DID is the primary key for this table.
How can I do this?

select MANAGERID,SUM(BDGT)
from N_DEPT
group by MANAGERID
order by SUM(BDGT) desc limit 1

You can do it like this:
SELECT aux.MANAGERID
FROM
(SELECT MANAGERID,
SUM(BUDGET) AS BDGT
FROM N_DEPT
GROUP BY MANAGERID) aux
INNER JOIN BDGTMGR b ON b.MANAGERID = aux.MANAGERID
WHERE b.BDGT = (select MAX(BDGT) FROM BDGTMGR);

The following query will work (modify depending on your flavour of SQL):
SELECT TOP 1 MANAGERID FROM N_DEPT GROUP BY MANAGERID ORDER BY SUM(BUDGET) DESC

Related

SQL Oracle Find Max of count

I have this table called item:
| PERSON_id | ITEM_id |
|------------------|----------------|
|------CP2---------|-----A03--------|
|------CP2---------|-----A02--------|
|------HB3---------|-----A02--------|
|------BW4---------|-----A01--------|
I need an SQL statement that would output the person with the most Items. Not really sure where to start either.
I advice you to use inner query for this purpose. the inner query is going to include group by and order by statement. and outer query will select the first statement which has the most items.
SELECT * FROM
(
SELECT PERSON_ID, COUNT(*) FROM TABLE1
GROUP BY PERSON_ID
ORDER BY 2 DESC
)
WHERE ROWNUM = 1
here is the fiddler link : http://sqlfiddle.com/#!4/4c4228/5
Locating the maximum of an aggregated column requires more than a single calculation, so here you can use a "common table expression" (cte) to hold the result and then re-use that result in a where clause:
with cte as (
select
person_id
, count(item_id) count_items
from mytable
group by
person_id
)
select
*
from cte
where count_items = (select max(count_items) from cte)
Note, if more than one person shares the same maximum count; more than one row will be returned bu this query.

Get Exclusive Count in SQL Server

I'm trying to get the count of PlanIds that are exclusive records for a certain location in an m-n table.
Imagine that I have the following table:
Id
PlanId
LocationId
I want to retrieve the count of PlanIds that only have one LocationId associated with it
What I have so far:
SELECT COUNT(PlanId)
FROM PLANLOCATION
WHERE PLANLOCATION = LocationId
Can you guys, help me, please?
Thank you
Here is one method, that uses two levels of aggregation:
SELECT COUNT(*)
FROM (SELECT PlanId
FROM PLANLOCATION
GROUP BY PlanId
HAVING MIN(LocationId) = MAX(LocationId)
) p;
Another method uses NOT EXISTS:
select count(distinct pl.planid)
from planlocation pl
where not exists (select 1
from planlocation pl2
where pl2.planid = pl.planid and
pl2.locationid <> pl.locationid
);
Note that count(distinct) can be just count(*) if planlocation has no duplicates.

SQL Select employees with work history in multiple states

I need a query that will show only employees who have been paid in more than one state.
The query will pull three columns:
EmployeeID
WorkLocation
LastPayDate
My current, unsuccessful attempt:
Select EmployeeID
, WorkLocation
, max(LastPayDate)
from Table
group by EmployeeID, WorkLocation
having COUNT(distinct WorkLocation) > 1
This query pulls zero records. I know there are employees who have worked in multiple states, however. I am not sure where my logic breaks down.
Any instruction is much appreciated.
You need to have a count(workLocation) > 1 which indicates that they have worked in more than 1 state. Specify this in the HAVING clause. Since you're only concerned in GROUPS which contain multiple WorkLocations.
If you're trying to check for multiple work locations within a specific year, you will perform that logic in the WHERE clause.
select EmployeeId
from table xyz
//where year(LastPayDate) == 2015
group by EmployeeId
having count(distinct WorkLocation) > 1
Figured it out. I needed to use a subquery. Solution as follows:
Select t.EmployeeID
, t.WorkLocation
, t.LastPayDate
From Table t
Where t.EmployeeID in
(
Select t2.EmployeeID
From Table t2
Group by t2.EmployeeID
Having count(distinct t2.WorkLocation) > 1
)
Group by t.EmployeeID, t.WorkLocation
Order by t.EmployeeID
Thanks to everyone for helping.

How to use select MIN() in SQL when one field can not be grouped?

I am quite new to SQL so please be gentle. I have tried search for an answer but can not find anything.
I have the following data in a table
Code Area Department Level Name
HWNET Highways Network Services 2 Bob Jones
HWNET Highways Network Services 1 Jim Smith
HWTRA Highways Traffic Services 2 Andy Johnson
HWTRA Highways Traffic Services 1 David Turner
I want to select all the columns from the table but only for the minimum value for each level. My problem is that I need to know the Name but this is stopping me from using the group by function
If I use this it brings back every row in the table
SELECT Code, Area, Department,MIN(Level) Level , Name
FROM TABLE_NAME
GROUP BY Code, Area,Department, Name
This brings back the correct rows but does not contain the Name.
SELECT Code, Area, Department,MIN(Level) Level
FROM TABLE_NAME
GROUP BY Code, Area,Department
Is there a way for me bring back this set of results?
Code Area Department Level Name
HWNET Highways Network Services 1 Jim Smith
HWTRA Highways Traffic Services 1 David Turner
Thanks is advance
select t.*
from TABLE_NAME t
inner join
(
SELECT Code, Area, Department,MIN(Level) mLevel
FROM TABLE_NAME
GROUP BY Code, Area,Department
) x on x.Code = t.code
and x.Area = t.area
and x.Department = t.Department
and x.mLevel = t.level
Usually I do it in this ways:
select *
from TABLE_NAME
where (Department,
Level) in (select Department,
min(Level)
from TABLE_NAME
group by Department)
Here a demo in SQL Fiddle.
Based on your data I used only Department and Level, but if you need to use also Code and Area to identify the right rows just ass them in the WHERE clause and in the SELECT of the subquery.
select *
from TABLE_NAME
where (Code,
Area
Department,
Level) in (select Code,
Area,
Department,
min(Level)
from TABLE_NAME
group by Code,
Area,
Department)
You could try something like
SELECT Code, Area, Department, Level, Name
FROM (
SELECT Code, Area, Department, Level, Name, ROW_NUMBER() OVER (PARTITION BY Code, Area, Department, Name ORDER BY Level) __RN
FROM TABLE_NAME) subQuery
WHERE __RN = 1
Without knowing more about the schema of the table, it's not easy to say what would be the best way of joining from a grouped version of your data to the table. Using ROW_NUMBER() is likely to be far more efficient, but you might be able to reduce the elements in your partition depending on what is actually the unique key in your table.
select
s.*
from table s,
(select
code, area, department, min(level) m
from
table
group by
code,area,department
) min_v
where
s.code = min_v.code
and s.area= min_v.area
and s.department = min_v.department
and s.level = min_v.m
;

SQL query, distinct rows needed

I have the following table structured like this:
So basically as you can see, the department goes through name changes every couple of years. Look at number 16 for example. I want a select query that will only get the name when the date is the greatest. How do I do that?
select ID, Name from departments o
where o.thedate=
(select max(i.thedate) from departments i where o.id=i.id)
SELECT ID,
First(Name) AS FirstOfName, First(DateChange) AS FirstOfDateChange
FROM departments
GROUP BY ID
ORDER BY First(DateChange) DESC;
What is the primary key for this table? This does a subquery the same table with a name comparison.
SELECT
id,
name,
date
FROM table
WHERE name = (SELECT TOP 1 name
FROM table AS subtable
WHERE subtable.name = table.name
ORDER BY date DESC)
SELECT d.*
FROM Departments d
INNER JOIN (SELECT pk
FROM Departments
GROUP BY ID
HAVING theDate=MAX(theDate)) m ON m.pk=d.pk
WHERE [Name]="Department"