我在编写查询时遇到问题,该查询将选择所有技能,加入员工和能力记录,但每位员工只返回一项技能,即他们最新的技能。使用此样本数据集
Skills
======
id employee_id competency_id created
1 1 1 Jan 1
2 2 2 Jan 1
3 1 2 Jan 3
Employees
===========
id first_name last_name
1 Mike Jones
2 Steve Smith
Competencies
============
id title
1 Problem Solving
2 Compassion
我想检索以下数据
Skill.id Skill.employee_id Skill.competency_id Skill.created Employee.id Employee.first_name Employee.last_name Competency.id Competency.title
2 2 2 Jan 1 2 Steve Smith 2 Compassion
3 1 2 Jan 3 1 Mike Jones 2 Compassion
我能够选择使用
创建的employee_id和maxSELECT MAX(created) as created, employee_id FROM skills GROUP BY employee_id
但是当我开始在select语句中添加更多字段或添加一个连接时,我得到'列'xyz'在选择列表中无效,因为它不包含在聚合函数或GROUP BY子句中。 “错误。
感谢任何帮助,我不必使用GROUP BY,这正是我所熟悉的。
答案 0 :(得分:3)
您获得的错误是因为如果使用了聚合函数,SQL Server要求SELECT
列表中的任何项都包含在GROUP BY
中。
问题在于,您可能在某些列中具有唯一值,这些值可能会导致结果失效。因此,您需要重写查询以使用以下方法之一:
您可以使用子查询来获得此结果。这将获得子查询中的max(created)
,然后您使用该结果来获取正确的员工记录:
select s.id SkillId,
s.employee_id,
s.competency_id,
s.created,
e.id employee,
e.first_name,
e.last_name,
c.id competency,
c.title
from Employees e
left join Skills s
on e.id = s.employee_id
inner join
(
SELECT MAX(created) as created, employee_id
FROM skills
GROUP BY employee_id
) s1
on s.employee_id = s1.employee_id
and s.created = s1.created
left join Competencies c
on s.competency_id = c.id
或者另一种方法是使用row_number()
:
select *
from
(
select s.id SkillId,
s.employee_id,
s.competency_id,
s.created,
e.id employee,
e.first_name,
e.last_name,
c.id competency,
c.title,
row_number() over(partition by s.employee_id
order by s.created desc) rn
from Employees e
left join Skills s
on e.id = s.employee_id
left join Competencies c
on s.competency_id = c.id
) src
where rn = 1
答案 1 :(得分:1)
对于您添加到SELECT
语句的每个非汇总列,您需要更新GROUP BY
以包含它。
此article可能会帮助您了解原因。
答案 2 :(得分:0)
;WITH
MAX_SKILL_created AS
(
SELECT
MAX(skills.created) as created,
skills.employee_id
FROM
skills
GROUP BY
skills.employee_id
),
MAX_SKILL_id AS
(
SELECT
MAX(skills.id) as id,
skills.employee_id
FROM
skills
INNER JOIN MAX_SKILL_created
ON MAX_SKILL_created.employee_id = skills.employee_id
AND MAX_SKILL_created.created = skills.created
GROUP BY
skills.employee_id
)
SELECT
* -- type all your columns here
FROM
employees
INNER JOIN MAX_SKILL_id
ON MAX_SKILL_id.employee_id = employees.employee_id
INNER JOIN skills
ON skills.id = MAX_SKILL_id.id
INNER JOIN competencies
ON competencies.id = skills.competency_id
答案 3 :(得分:0)
如果您使用的是SQL Server,则可以使用OUTER APPLY
SELECT *
FROM employees E
OUTER APPLY (
SELECT TOP 1 *
FROM skills
WHERE employee_id = E.id
ORDER BY created DESC
) S
INNER JOIN competencies C
ON C.id = S.competency_id