2009-03-30 2 views
1

У меня есть две таблицы (Управление и Сотрудник).SQL Query Question (Возможный Присоединиться/Подзапрос?)

В таблице руководства отслеживаются различные команды управления, управляющие компанией X за последние несколько лет. Каждой команде управления присваивается идентификатор (например, managementnr), и каждая команда имеет генерального директора (а именно, ceoname).

таблица Сотрудник отслеживает сотрудников, работающих в компании X (в основном только их имена и какие команды управления нанял их)

Вот код SQL:


CREATE TABLE EMPLOYEE(
    EMPLOYEENAME VARCHAR2(15) NOT NULL, 
    HIRETEAM NUMBER(2), 
    PRIMARY KEY (EMPLOYEENAME) 
    ); 

CREATE TABLE MANAGEMENT(
    MANAGEMENTNR NUMBER(2) NOT NULL, 
    CEONAME VARCHAR2(20) NOT NULL, 
    PRIMARY KEY (MANAGEMENTNR,CEONAME) 
    ); 

Я пытаюсь сформировать SQL чтобы получить управлениеNR, в котором было нанято самое большое количество сотрудников. Я попытался с помощью:

SELECT HIRETEAM,max(count(HIRETEAM)) 
from EMPLOYEE 
group by HIRETEAM 

но я получаю:

ORA-00937: not a single-group group function 

(я использую Oracle)

После нескольких часов Google-фу, я, наконец, понять, что эта ошибка означает, однако я до сих пор не могу придумать какой-либо другой способ сформировать этот запрос. Я пробовал использовать подзапросы/объединения, но все равно ничего. Я очень новичок в SQL в целом. Если кто-нибудь может помочь, я буду очень благодарен!

Спасибо за ваше время =]
--Evan Лестрейндж

ответ

2

Получить первую строку из этого запроса:

select hireteam,count(*) from EMPLOYEE group by hireteam order by count(*) desc 
0

Таким образом, вы получите все команды с числом наемных работников.

select 
    Management.ManagementNr, 
    Management.CeoName, 
    count(Employee.EmployeeName) 
from 
    Employee 
inner join 
    Management on Employee.HireTeam = Management.ManagementNr 
group by 
    Management.ManagementNr 
order by 
    count(Employee.EmployeeName) desc 

Добавление дополнительного имеющего положение и отказ от объединения (поскольку имя CEO не требуется, поскольку я только признал), вы получите желаемый результат следующим образом.

Это может фактически вернуть несколько строк, если несколько руководителей наняли одинаковое количество сотрудников. И это уродливо ... но ad hoc Я не знаю лучшего способа сделать это в одном запросе.

+0

Моих глаза они кровоточат;) – karim79

+0

я просто скопировал соглашение об именах ... и abdonned быстро ...: D –

3

Я думаю, что вы ищете это:

WITH counts_hireteam as (
    SELECT HIRETEAM 
     , count(*) count_hireteam 
    from EMPLOYEE 
    group by HIRETEAM 
    order by count(*) desc 
) 
select HIRETEAM 
    from counts_hireteam 
where rownum = 1; 
2

«Правильный» способ сделать это на самом деле что-то вроде:

SELECT m.ceoname, COUNT(1), ROW_NUMBER() OVER (ORDER BY COUNT(1) DESC) 
FROM management m 
JOIN employee e ON m.managementnr = e.hireteam 
GROUP BY m.ceoname 

Вы получаете в murkky области Топ- N запросов, и я направлю вас на это excellent column of Ask Tom on Top-N. Другие ответы работают в простых случаях, но это когда вы начинаете хотеть делать такие вещи, как возвращение трех лучших команд управления (по подсчету) и постоянное выполнение этих проблем.

Консистенция - ключевой момент.Как отмечает Том:

Делает предложения GROUP BY в запросе гарантии , что выходные данные будут отсортированы по GROUP BY столбцов в порядке, даже если нет ORDER BY статьи?

Если и пока не является ORDER BY заявления на запросе, строки возвращаемых не могут не считаться в любом заказе. Без ORDER BY данные могут быть возвращены в любом порядке в диапазоне , что делает база данных, например, , вернув ее. Это всегда было true и всегда будет правдой.

В самом деле, в Oracle Database 10g Release 2 , вы увидите GROUP BY возвращает данные в случайном порядке гораздо чаще, чем раньше:

Используя этот образец данных:

INSERT INTO employee VALUES ('Bob',1); 
INSERT INTO employee VALUES ('Sue',1); 
INSERT INTO employee VALUES ('John',1); 
INSERT INTO employee VALUES ('James',2); 
INSERT INTO employee VALUES ('Mary',2); 
INSERT INTO employee VALUES ('Ron', 2); 
INSERT INTO employee VALUES ('Jane',3); 
INSERT INTO employee VALUES ('Luke',4); 
INSERT INTO employee VALUES ('Rob',4); 
INSERT INTO employee VALUES ('Tim', 5); 

INSERT INTO management VALUES (1, 'Kate'); 
INSERT INTO management VALUES (2, 'Larry'); 
INSERT INTO management VALUES (3, 'Jake'); 
INSERT INTO management VALUES (4, 'Sarah'); 
INSERT INTO management VALUES (5, 'Tom'); 
0

Если вы хотите ограничить результаты одной записи, даже в случае связи для наибольшего числа нанимает:

select * from (
    select hireteam, count(hireteam) count 
    from employee 
    group by hireteam 
    order by count(hireteam) desc, hireteam asc) 
where rownum = 1 

Чтобы получить все значения hireteam, имеющие наибольшее количество назначений (в том числе связей):

select * from (
    select hireteam, 
      count(hireteam) count, 
      rank() over (order by count(hireteam) desc) rank 
    from employee 
    group by hireteam) 
where rank = 1;