1

すべてのスキルを選択し、従業員とコンピテンシーのレコードを結合するクエリを作成するのに問題がありますが、従業員ごとに最新のスキルであるスキルを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

しかし、selectステートメントにフィールドを追加したり、結合を追加したりすると、集計関数にもGROUP BY句にも含まれていないため、選択リストで「列」xyzが無効になります。エラー。

どんな助けでもありがたいです、そして私はGROUPBYを使う必要はありません、それは私が精通しているものです。

4

4 に答える 4

3

発生したエラーは、使用されている集計関数がある場合、SQLServer では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 FiddlewithDemoを参照してください

または、これを行う別の方法は、次を使用すること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 FiddlewithDemoを参照してください

于 2013-01-30T16:02:04.963 に答える
1

ステートメントに追加するすべての非集計列について、それを含めるようSELECTに更新する必要があります。GROUP BY

この記事は、その理由を理解するのに役立つ場合があります。

于 2013-01-30T16:00:24.390 に答える
0

SQL Serverを使用している場合は、OUTERAPPLYを使用できます。

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 に答える