web-dev-qa-db-ja.com

複数の行の同じ列を1つの行に結合する

Employee_IDに基づいて、2つのテーブルHRUserDefinedを結合しています:

HRテーブル

First Name  Last Name   Employee_ID
----------  ---------   -----------
Joe         Smith       456654

ユーザー定義テーブル

Area    ud_1_text   ud_2_text   Employee_ID
----    ---------   ----------  -----------
1       ABCD1234    31/08/2018  456654
2       69090       23/05/2022  456654

Area1と等しい場合は「ドライバーライセンス」であり、Area2と等しい場合は「応急処置証明書」であることがわかりました。

Employee_IDごとに1行で以下を返すことができるようにしたいと思います。

Employee_ID First Name  Last name   D/L Number  Expiry      First Aid Expiry
----------- ----------  ---------   ----------  ----------  --------- ----------
456654      Joe         Smith       ABCD1234    31/08/2018  69090     23/05/2022

これを行う方法に関するアイデアはありますか? Microsoft SQL Serverクエリをしてください。

2
Craig Whalland

User Defined Tableに2回参加します。1回はArea = 1で、1回はArea = 2で参加します。

from [HR Table] as HT
  inner join [User Defined Table] as UT1
    on HT.Employee_ID = UT1.Employee_ID and
       UT1.Area = 1
  inner join [User Defined Table] as UT2
    on HT.Employee_ID = UT2.Employee_ID and
       UT2.Area = 2

D/L NumberからUT1Expiryから取得First AidExpiryからUT2から取得

2
Mikael Eriksson

@Aduguidからcteコードを取得した、別の方法は

;WITH
hr_table
AS
(
    SELECT tbl.* FROM (VALUES
      ( 'Joe', 'Smith', 456654)
    ) tbl ([First Name], [Last Name], [Employee_ID]) 
)
, 
user_defined_table
AS
(
    SELECT tbl.* FROM (VALUES
      ( 1, 'ABCD1234', '31-Aug-2018', 456654)
    , ( 2, '69090', '23-May-2022', 456654)
    ) tbl ([Area], [ud_1_text], [ud_2_text], [Employee_ID]) 
)

SELECT h.Employee_ID,h.[First Name],h.[Last Name],
MAX(CASE WHEN u.Area=1 THEN u.ud_1_text ELSE '' END) AS [D/L Number],
MAX(CASE WHEN u.Area=1 THEN u.ud_2_text ELSE '' END) AS [expiry],
MAX(CASE WHEN u.Area=2 THEN u.ud_1_text ELSE '' END) AS [First Aid],
MAX(CASE WHEN u.Area=2 THEN u.ud_2_text ELSE '' END) AS [expiry]
 FROM hr_table h
INNER JOIN user_defined_table u
ON h.Employee_ID=u.Employee_ID
GROUP BY h.Employee_ID,h.[First Name],h.[Last Name]

3
Biju jose

PIVOT を使用してこれを実現できます。

WITH
hr_table
AS
(
    SELECT tbl.* FROM (VALUES
      ( 'Joe', 'Smith', 456654)
    ) tbl ([First Name], [Last Name], [Employee_ID]) 
)
, 
user_defined_label
AS
(
    SELECT tbl.* FROM (VALUES
      ( 1, 'Drivers Licence')
    , ( 2, 'First Aid Cerification')
    ) tbl ([Area], [Description]) 
)
,
user_defined_table
AS
(
    SELECT tbl.* FROM (VALUES
      ( 1, 'ABCD1234', '31-Aug-2018', 456654)
    , ( 2, '69090', '23-May-2022', 456654)
    ) tbl ([Area], [ud_1_text], [ud_2_text], [Employee_ID]) 
)
, 
user_defined_list
AS
(
    SELECT
          hr.[First Name]
        , hr.[Last Name]
        , hr.[Employee_ID]
        , val.[Area]
        , lbl.[Description]
        , val.[ud_1_text]
        , val.[ud_2_text]
    FROM 
        hr_table AS hr
        INNER JOIN user_defined_table AS val ON hr.[Employee_ID] = val.[Employee_ID]
        INNER JOIN user_defined_label AS lbl ON val.[Area] = lbl.[Area]
)
SELECT 
      dsc.[First Name]
    , dsc.[Last Name]
    , dsc.[Employee_ID]
    , dsc.[Drivers Licence] 
    , [Drivers Licence Expiry] = dte.[Drivers Licence] 
    , dsc.[First Aid Cerification]
    , [First Aid Cerification Expiry] = dte.[First Aid Cerification]
FROM 
    (
    SELECT 
          ud.[First Name]
        , ud.[Last Name]
        , ud.[Employee_ID]
        , ud.[Description]
        , ud.[ud_1_text]
    FROM 
        user_defined_list AS ud
    ) AS ud
        PIVOT
            (
            MAX(ud.[ud_1_text]) 
            FOR ud.[Description] IN ([Drivers Licence], [First Aid Cerification])
            ) AS dsc
        INNER JOIN (
        SELECT 
              ds.[Employee_ID]
            , ds.[Drivers Licence] 
            , ds.[First Aid Cerification]
        FROM 
            (
            SELECT
                  ud.[First Name]
                , ud.[Last Name]
                , ud.[Employee_ID]
                , ud.[Description]
                , ud.[ud_2_text]
            FROM 
                user_defined_list AS ud
            ) AS ud
        PIVOT
            (MAX(ud.[ud_2_text]) 
            FOR ud.[Description] IN ([Drivers Licence], [First Aid Cerification])) AS ds 
    ) AS dte ON dte.[Employee_ID] = dsc.[Employee_ID]

screenshot

1
aduguid