web-dev-qa-db-fra.com

Combinez la même colonne de plusieurs lignes en une seule ligne

Je joins deux tables HR et UserDefined basées sur le Employee_ID:

Tableau HR

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

Tableau défini par l'utilisateur

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

Maintenant, je sais que si Area est égal à 1 alors c'est une "licence de pilote" et si Area est égal à 2 qu'il s'agit d'une "certification en secourisme".

Je voudrais pouvoir renvoyer ce qui suit sur une ligne par Employee_ID:

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

Auriez vous des idées pour faire ça? Requête Microsoft SQL Server s'il vous plaît.

2
Craig Whalland

Se joindre à User Defined Table deux fois, une fois avec Area = 1 et une fois avec 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

Obtenir le D/L Number avec Expiry de UT1 et First Aid avec Expiry de UT2

2
Mikael Eriksson

Pris le code cte de @Aduguid, une autre alternative est

;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

Vous pouvez utiliser le PIVOT pour y parvenir.

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