SQL - select distinct records in one field with highest records from another field

人走茶凉 提交于 2020-01-13 03:57:11

问题


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          55         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.


回答1:


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.




回答2:


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)




回答3:


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




回答4:


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);


来源:https://stackoverflow.com/questions/2130131/sql-select-distinct-records-in-one-field-with-highest-records-from-another-fie

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!