2

専門家の助けが必要です。少なくともこの時点までは、SQL をよく知っていると思っていました。私は SQL Server を使用しており、登録された各メンバーを一覧表示し、各ゲストの名前を行ではなく個別の列に表示するクエリを作成する必要があります。各メンバーは、各メンバーに関連付けられた 0:N のゲストを持つことができます。だから、ここに私のテーブルがあります:

メンバー テーブル: memberID (PK)、FName、LName、...

ゲスト テーブル: GuestID (PK)、FName、LastName、...

イベント テーブル: GuestID (PK)、MemberID (PK)、...

次のようなクエリ出力を作成しようとしています。

メンバーID | Member_FName | Member_LName | Guest1ID | Guest1_Fname | Guest2ID | Guest2_FName ...

サンプル:

Member Table
MemberID | FName | LName
001        Frank   Smith   
002        Mary    Jane
003        John    Henry

Guest Table
GuestID | FName | LName
101       Steve   Smith
102       Peter   Smith
103       Mike    Jane

Event Table
MemberID | GuestID
001        101
001        102
002        103

出力:

MemberID | FName | LName| GuestID1 | FName1 | LName1 |GuestID2 | FName2 | LName2
001        Frank   Smith  101        Steve    Smith   102        Peter    Smith
002        Mary    Jane   103        Mike     Jane
003        John    Henry

他の情報を含める必要がある場合はお知らせください。

前もって感謝します!

4

2 に答える 2

3

UNPIVOT結果を取得するために、関数と関数の両方を実装できPIVOTます。はUNPIVOT列を取得してデータを行に変換し、ピボットは最終結果を取得して列に戻します。

select MemberID,
  memberfirst,
  memberlast,
  isNull(GuestId_1, '') GuestId_1, 
  isNull(fname_1, '') fname_1, 
  isNull(lname_1, '') lname_1,
  isNull(GuestId_2, '') GuestId_2, 
  isNull(fname_2, '') fname_2, 
  isNull(lname_2, '') lname_2
from
(
  select MemberID,
    memberfirst,
    memberlast,
    col+'_'+cast(rn as varchar(10)) col,
    value
  from
  (
    select m.MemberID,
      m.fname MemberFirst,
      m.lname MemberLast,
      isNull(cast(g.GuestID as varchar(5)), '') GuestId,
      isNull(g.fname, '') fname,
      isNull(g.lname, '') lname,
      row_number() over(partition by m.parentid order by g.guestid) rn
    from member m
    left join Event r
      on m.parentid = r.memberid
    left join guest g
      on r.guestid = g.guestid
  ) src
  unpivot
  (
    value
    for col in (GuestId, fname, lname)
  ) unpiv
) src1
pivot
(
  max(value)
  for col in (GuestId_1, fname_1, lname_1,
              GuestId_2, fname_2, lname_2)
) piv

SQL FiddlewithDemoを参照してください

上記は、レコードの数を事前に知っている場合はうまく機能しますが、そうでない場合は、動的SQLを使用することをお勧めします。

DECLARE  @query  AS NVARCHAR(MAX),
    @colsPivot as  NVARCHAR(MAX),
    @colsPivotNull as  NVARCHAR(MAX)

select @colsPivot = STUFF((SELECT  ',' 
                      + quotename(c.name +'_'+ cast(t.rn as varchar(10)))
                    from
                    (
                      select cast(row_number() over(partition by m.MemberID order by g.guestid) as varchar(50)) rn
                      from member m
                      left join Event r
                        on m.parentid = r.memberid
                      left join guest g
                        on r.guestid = g.guestid
                    ) t
                    cross apply sys.columns as C
                   where C.object_id = object_id('guest')
                   group by c.name, t.rn
                   order by t.rn
            FOR XML PATH(''), TYPE
            ).value('.', 'NVARCHAR(MAX)') 
        ,1,1,'')

select @colsPivotNull = STUFF((SELECT  ', IsNull(' 
                      + quotename(c.name +'_'+ cast(t.rn as varchar(10)))+', '''') as '+c.name +'_'+ cast(t.rn as varchar(10))
                    from
                    (
                      select cast(row_number() over(partition by m.MemberID order by g.guestid) as varchar(50)) rn
                      from member m
                      left join Event r
                        on m.parentid = r.memberid
                      left join guest g
                        on r.guestid = g.guestid
                    ) t
                    cross apply sys.columns as C
                   where C.object_id = object_id('guest')
                   group by c.name, t.rn
                   order by t.rn
            FOR XML PATH(''), TYPE
            ).value('.', 'NVARCHAR(MAX)') 
        ,1,1,'')

set @query 
  = 'select 
          MemberID,
          memberfirst,
          memberlast, '+@colsPivotNull+'
      from
      (
        select MemberID,
          memberfirst,
          memberlast,
          col+''_''+cast(rn as varchar(10)) col,
          value
        from 
        (
          select m.MemberID,
            m.fname MemberFirst,
            m.lname MemberLast,
            isNull(cast(g.GuestID as varchar(5)), '''') GuestId,
            isNull(g.fname, '''') fname,
            isNull(g.lname, '''') lname,
            row_number() over(partition by m.parentid order by g.guestid) rn
          from member m
          left join Event r
            on m.parentid = r.memberid
          left join guest g
            on r.guestid = g.guestid
        ) x
        unpivot
        (
         value
          for col in (GuestId, fname, lname)
        ) u
      ) x1
      pivot
      (
        max(value)
        for col in ('+ @colspivot +')
      ) p'

exec(@query)

SQL FiddlewithDemoを参照してください

どちらのバージョンでも同じ結果が得られます。

| MemberID | MEMBERFIRST | MEMBERLAST | GUESTID_1 | FNAME_1 | LNAME_1 | GUESTID_2 | FNAME_2 | LNAME_2 |
-------------------------------------------------------------------------------------------------------
|        1 |       Frank |      Smith |       101 |   Steve |   Smith |       102 |   Peter |   Smith |
|        2 |        Mary |       Jane |       103 |    Mike |    Jane |           |         |         |
|        3 |        John |      Henry |           |         |         |           |         |         |
于 2013-01-09T20:46:22.813 に答える
0

実際には、ゲスト用に 1 つの列を作成し、カンマ区切りのリストを作成する方が簡単です。

次のようにできます。

SELECT DISTINCT memberID, FName, LName, 
 STUFF((SELECT ', ' + FName + ' ' + LName + ' ('+GuestID+')'
  FROM Relationship R 
  JOIN Guest G ON R.GuestID = G.GuestID
  WHERE R.MemberID = Memeber.MemberID
  FOR XML PATH ('')),1,2,'') AS GuestList
FROM Member

それは次のようになります。

MemberID | FName | LName| GuestList
001        Frank   Smith  Steve Smith (101), Peter Smith (102)
002        Mary    Jane   Mike Jane (103)
003        John    Henry
于 2013-01-09T20:35:41.137 に答える