1

我在编写查询时遇到问题,该查询将选择所有技能,加入员工和能力记录,但每个员工只返回一项技能,即他们的最新技能。使用此示例数据集

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和max

SELECT MAX(created) as created, employee_id  FROM skills GROUP BY employee_id

但是,当我开始在选择语句中添加更多字段或添加连接时,我得到“列 'xyz' 在选择列表中无效,因为它不包含在聚合函数或 GROUP BY 子句中。” 错误。

任何帮助表示赞赏,我不必使用 GROUP BY,这正是我所熟悉的。

4

4 回答 4

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

请参阅带有演示的 SQL Fiddle

或者另一种方法是使用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

请参阅带有演示的 SQL Fiddle

于 2013-01-30T16:02:04.963 回答
1

对于您添加到语句中的每个非聚合列,SELECT您需要更新您的GROUP BY以包含它。

本文可能会帮助您了解原因。

于 2013-01-30T16:00:24.390 回答
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
于 2013-01-30T16:11:13.103 回答
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
于 2013-01-30T16:05:06.500 回答