SQL - выбор различных записей в одном поле с наибольшим количеством записей из другого поля
-
22-09-2019 - |
Вопрос
В сценарии, где у меня есть таблица, подобная такой:
int id (PK)
int staff_id
int skill_id
bit mainskill
Я хочу выбрать только ОДНУ запись для каждого сотрудника (представленную staff_id) с перечислением их основного навыка, представленного a (1) в mainskill.Если основной навык отсутствует, я хочу вернуть любую из записей навыков для этого сотрудника.Например:
id staff_id skill_id mainskill
1 1 24 1
2 1 55 0
3 1 7 0
4 4 24 0
5 4 18 0
6 6 3 0
7 6 18 1
Запрос должен возвращать:
id staff_id skill_id mainskill
1 1 24 1
4 4 24 0
7 6 18 1
Я пробовал различные комбинации группирования, РАЗЛИЧЕНИЯ и т.д., Но не могу получить желаемый результат.Любая помощь приветствуется.
Решение
SQL Server 2005+, Использующий CTE:
WITH rows AS (
SELECT t.id,
t.staff_id,
t.skill_id,
t.mainskill,
ROW_NUMBER() OVER (PARTITION BY t.staff_id ORDER BY t.mainskill DESC) AS rank
FROM TABLE t)
SELECT r.id,
r.staff_id,
r.skill_id,
r.mainskill
FROM rows r
WHERE r.rank = 1
ORDER BY r.staff_id
SQL Server 2005+, Не эквивалентный CTE:
SELECT r.id,
r.staff_id,
r.skill_id,
r.mainskill
FROM (SELECT t.id,
t.staff_id,
t.skill_id,
t.mainskill,
ROW_NUMBER() OVER (PARTITION BY t.staff_id ORDER BY t.mainskill DESC) AS rank
FROM TABLE t) r
WHERE r.rank = 1
ORDER BY r.staff_id
Оба используют НОМЕР СТРОКИ, который доступен только с SQL Server 2005.
Другие советы
Если вы объедините основной навык в передней части идентификатора skillid, max предоставит вам либо основной навык, либо другой, в котором основного навыка не существует.
ВЫБЕРИТЕ t.id , t.staff_id, t.skill_id, t.mainskill, ИЗ ТАБЛИЦЫ t, Где ПРИВЕДЕНИЕ (т.mainskill Как Varchar(5))+'-'+ Приведение(т.skill_id как varchar(5)) В (ВЫБЕРИТЕ МАКСИМАЛЬНОЕ(ПРИВЕДЕНИЕ (т.mainskill как Varchar(5))+'-'+ Приведение(т.skill_id как varchar(5))) ИЗ ТАБЛИЦА t ГРУППИРУЕТСЯ По t.staff_id)
MySQL - сервер
select * from staff_skill;
id staff_id skill_id mainskill
---------- ---------- ---------- ----------
1 1 24 1
2 1 55 0
3 1 7 0
4 4 24 0
5 4 18 0
6 6 3 0
7 6 18 1
7 rows selected
select * from staff_skill x
where skill_id =
(select y.skill_id from staff_skill y
where y.staff_id = x.staff_id
order by y.mainskill desc, y.skill_id desc limit 1);
id staff_id skill_id mainskill
---------- ---------- ---------- ----------
1 1 24 1
4 4 24 0
7 6 18 1
3 rows selected
- Йен
Oracle
как насчет:
(staff_skill - это ваш стол)
select * from staff_skill x where
skill_id =
(select skill_id from
(select * from staff_skill
order by mainskill desc, skill_id desc)
where staff_id = x.staff_id and rownum = 1);