In a scenario where I have a table like so:
int id (PK)
int staff_id
int skill_id
bit mainskill
I want to select only ONE record for each staff member (represented by staff_id) listing their main skill as represented by a (1) in mainskill. If no main skill is present, I want to return any of the skill records for that staff member. For example:
id staff_id skill_id mainskill
1 1 24 1
2 1 5开发者_如何学编程5 0
3 1 7 0
4 4 24 0
5 4 18 0
6 6 3 0
7 6 18 1
The query should return:
id staff_id skill_id mainskill
1 1 24 1
4 4 24 0
7 6 18 1
I've tried various combinations of grouping, DISTINCT etc but can't get the output I'm after. Any help appreciated.
SQL Server 2005+, Using 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+, Non-CTE Equivalent:
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
Both use ROW_NUMBER, which is only available since SQL Server 2005.
If you concatenate the mainskill on the front of the skillid, max will give you either the mainskill or one other where mainskill doesn't exist.
SELECT t.id, t.staff_id, t.skill_id, t.mainskill, FROM TABLE t WHERE CAST(t.mainskill As Varchar(5))+'-'+ Cast(t.skill_id as varchar(5)) IN (SELECT MAX(CAST(t.mainskill As Varchar(5))+'-'+ Cast(t.skill_id as varchar(5))) FROM TABLE t GROUP BY 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
- Ian
Oracle
how about:
(staff_skill is your table)
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);
精彩评论