5

私は2つのテーブルを持っています

部門

ID  Dept
---------
1   HR
2   Accts
3   IT

従業員

ID Name     Depts
-------------------
1  Kevin     2,1
2  Michelle  1
3  Troy      1,3
4  Rheesa    2,3,1

SQLクエリで次のような出力を探しています。

従業員部門

ID Name      Depts
-------------------------
 1 Kevin     Accts,HR
 2 Michelle  HR
 3 Troy      HR,IT
 4 Rheesa    Accts,IT,HR

sを部門と結合する次のことを試しましたが、部門ごとに1行だけになります。クエリを使用して上記の結果を取得するにはどうすればよいですか?

select 
    name, depts, dept 
from 
    employee
CROSS APPLY  
    dbo.split_list(employee.depts ,',') split
inner join 
    dbo.department on  depts= split.value
order by 
    name
4

5 に答える 5

7
DECLARE @Departments TABLE 
(
  ID INT PRIMARY KEY, 
  Dept VARCHAR(32) NOT NULL UNIQUE
);

DECLARE @Employees TABLE
(
  ID INT PRIMARY KEY,
  Name NVARCHAR(64) NOT NULL,
  Depts VARCHAR(255) NOT NULL
);

INSERT @Departments VALUES 
  (1,'HR'),  (2,'Accts'),  (3,'IT');

INSERT @Employees VALUES
  (1,'Kevin','2,1'), (2,'Michelle','1'),
  (3,'Troy','1,3'),  (4,'Rheesa','2,3,1');

SELECT ID, Name, Depts = STUFF((SELECT ',' + d.Dept 
    FROM @Departments AS d
    INNER JOIN @Employees AS ei
    ON ',' + ei.Depts + ',' LIKE '%,' + CONVERT(VARCHAR(12), d.id) + ',%'
    WHERE ei.ID = e.ID
    ORDER BY Dept
    FOR XML PATH, 
    TYPE).value(N'/text().[1]', N'nvarchar(max)'), 1, 1, N'')
FROM @Employees AS e
ORDER BY ID;

順序付けが決定論的であるため (部署名順)、結果は必要な結果と完全には一致しません。

ID      Name        Depts
----    --------    ----
1       Kevin       Accts,HR
2       Michelle    HR
3       Troy        HR,IT
4       Rheesa      Accts,HR,IT

カンマ区切りリストの出現順に並べたい場合は、次のように変更します。

ORDER BY Dept

に:

ORDER BY CHARINDEX( ',' + CONVERT(VARCHAR(12), d.id) + ',', ',' + ei.Depts + ',')

結果:

ID      Name        Depts
----    --------    ----
1       Kevin       Accts,HR
2       Michelle    HR
3       Troy        HR,IT
4       Rheesa      Accts,IT,HR -- this is the only one affected as it turns out

ただし、実際には、データベースを正規化する必要があります。これは絶対的な悪夢です。

于 2013-01-30T20:26:01.280 に答える
3

データの保存方法を超えて、私がお手伝いします。

さて、あなたはここで多くの質問をしています。まず、データを分割するには、データを XML としてフォーマットし、CROSS APPLY を使用します。これは、組み込み関数を必要としないトリックです。

これにより、コンマ区切りの文字列が文字列のリストに変換されます。次に、FOR XML を使用してそれらを元に戻すことができます。

これを試してみてください:

SELECT
   E.Id, 
   E.Name, 
   STUFF(
        (
        SELECT ',' +  D.Department AS [text()]
        FROM  (
           SELECT A.[id],  
             Split.a.value('.', 'VARCHAR(100)') AS DeptId  
           FROM  
              (SELECT [id],  
                 CAST ('<M>' + REPLACE(Depts, ',', '</M><M>') + '</M>' AS XML) AS String  
              FROM  Employee
          ) AS A 
        CROSS APPLY String.nodes ('/M') AS Split(a)) A 
        JOIN Departments D ON A.DeptId = D.Id
        WHERE E.Id = A.Id
        FOR XML PATH('')
        ), 1, 1, '') AS Departments
FROM Employee E

そして、ここにSQL Fiddleがあります。

幸運を。

于 2013-01-30T20:06:21.890 に答える
2

再帰 CTE を使用してデータを分割し、次に使用FOR XML PATHして行を 1 行に連結することもできます。

;with cte (id, name, deptid, depts) as
(
  select id, name,
    cast(left(depts, charindex(',',depts+',')-1) as varchar(50)) deptid,
         stuff(depts, 1, charindex(',',depts+','), '') depts
  from employee
  union all
  select id, name,
    cast(left(depts, charindex(',',depts+',')-1) as varchar(50)) deptid,
    stuff(depts, 1, charindex(',',depts+','), '') depts
  from cte
  where depts > ''
) 
select e.id, e.name,
  stuff((
         select distinct ', '+ d.dept
         from cte c
         inner join departments d
            on c.deptid = d.id
         where e.id = c.id
         for XML path('')),1,1,'') Depts
from employee e

デモで SQL Fiddle を参照してください

結果:

| ID |     NAME |          DEPTS |
----------------------------------
|  1 |    Kevin |      Accts, HR |
|  2 | Michelle |             HR |
|  3 |     Troy |         HR, IT |
|  4 |   Rheesa |  Accts, HR, IT |
于 2013-01-30T20:34:25.000 に答える
1

また、動的管理機能sys.dm_fts_parser
でオプションを使用することもできます 。スクリプトを実行する前に、フルテキスト コンポーネントがインストールされていることを確認する必要があります。

SELECT FULLTEXTSERVICEPROPERTY ('IsFulltextInstalled')

0 = フルテキストはインストールされていません。1 = フルテキストがインストールされています。NULL = 無効な入力またはエラー。

0 = フルテキストがインストールされていない場合は、この投稿が必要ですSQL Server 2008 にフルテキストをインストールする方法は?

SELECT b.ID, b.Name, STUFF((
SELECT ',' + d.Dept
FROM Employees e 
  JOIN Departments d ON d.ID IN(
                                SELECT display_term 
                                FROM sys.dm_fts_parser('"' + e.Depts + '"', 1033, NULL, 0) 
                                WHERE display_term NOT LIKE 'nn%'
                                )
WHERE b.ID = e.ID
ORDER BY d.Dept
FOR XML PATH('')), 1, 1, '') AS Depts
FROM Employees b

また

SELECT e.ID, e.Name, 
 (
  STUFF((
  SELECT ',' + Dept
  FROM sys.dm_fts_parser('"' + e.Depts + '"', 1033, NULL, 0) p JOIN Departments d ON p.display_term = d.ID
  WHERE display_term NOT LIKE 'nn%'
  FOR XML PATH('')), 1, 1, '')
  ) AS Depts
 FROM Employees e
于 2013-01-30T21:51:53.023 に答える