-1

これがどこかで回答されている場合は申し訳ありません。検索しましたが、回答が見つかりません。

3 つの SQL テーブルがあります: 従業員テーブル (ID、名前など...) キー スキル テーブル (ID、スキル名) リンク テーブル (従業員 ID、スキル ID)

従業員は明らかに複数の重要なスキルを持つことができますが、次のように「従業員レポート」として 1 行で報告しようとしています。

行 1 - 名前、生年月日、キー スキル 1、キー スキル 2 など.... 行 2 - 名前、生年月日、キー スキル 1、キー スキル 2 など....

次を使用して、スキルを行数として返すことができます。

SELECT DISTINCT kst.KeySkillName FROM KeySkillsTable
    INNER JOIN KeySkillsLinkTable kslt ON kslt.EmployeeId = 2
    INNER JOIN KeySkillsTable kst ON kst.Id = kslt.KeySkillsId

しかし、これをサブクエリとしてより大きな選択に入れると、次のエラーが発生します。

サブクエリが複数の値を返しました。サブクエリが =、!=、<、<=、>、>= の後にある場合、またはサブクエリが式として使用されている場合、これは許可されません。

これは、必要な複数の列ではなく、サブクエリが複数の行を返すためだと思います。

事前に感謝します。

4

1 に答える 1

4

このタイプの変換は、PIVOT. 列の値をハードコーディングする静的ピボットと、実行時に列が決定される動的ピボットの 2 つの方法があります。これは、状況に応じてこれを行う方法の例です。

静的ピボット ( SQL Fiddle with Demoを参照)

select *
from 
(
  select e.id, e.name, s.skillname, count(*) cnt
  from employee e
  left join emp_skill es
    on e.id = es.emp_id
  left join skills s
    on es.skill_id = s.id
  group by e.id, e.name, s.skillname
) x
pivot
(
  sum(cnt)
  for skillname in([skill 1], [skill 2], [skill 3])
) p

動的ピボット ( SQL Fiddle with Demoを参照)

DECLARE @cols AS NVARCHAR(MAX),
    @query  AS NVARCHAR(MAX)

select @cols = STUFF((SELECT distinct ',' + QUOTENAME(skillname) 
                    from skills
            FOR XML PATH(''), TYPE
            ).value('.', 'NVARCHAR(MAX)') 
        ,1,1,'')


set @query 
      = 'SELECT id, name,' + @cols + ' from 
         (
            select e.id, e.name, s.skillname, count(*) cnt
            from employee e
            left join emp_skill es
              on e.id = es.emp_id
            left join skills s
              on es.skill_id = s.id
            group by e.id, e.name, s.skillname
         ) x
         pivot 
         (
            sum(cnt)
            for skillname in(' + @cols + ')
         ) p '

execute(@query)

どちらのクエリでも同じ結果が生成されます。違いは、最初に、列にしたいすべての値をコーディングする必要があることです。

于 2012-08-19T23:51:43.617 に答える