2015-10-08 40 views
0

請問您能幫助我嗎?我使用的是SQL如下所示:SQL在水平選擇連接的情況下

SELECT 
    DISTINCT C.Field1 As 'Group', 
    A.Field2 As 'Security Object' 
    E.Field3 As 'User' 
FROM TableA AS A 
JOIN TableB AS B ON B.key1 = A.Key1 
JOIN TableC AS C ON C.Key1 = B.key2 
JOIN TableD AS D ON D.key1 = C.key2 
where A.Field1 = 'ObjectA' 
GROUP BY C.Field1, A.Field2, E.Field3 

典型輸出

Group Security Object User 
Group1 ObjectA UserA 
Group1 ObjectA UserB 
Group1 ObjectA UserC 
Group2 ObjectA UserE 
Group2 ObjectA UserF 
Group2 ObjectA UserH 
etc... 

我要輸出更多的東西一樣:

Group Security Object User 
Group1 ObjectA UserA, UserB, UserC 
Group2 ObjectA UserE, UserF, UserH 
etc 

但是我有困難的連接用戶領域在所示的水平形式中。你能幫我嗎? 我知道有很多關於這個網上,但沒有什麼是:-( J.

+1

爲什麼不同組時由?爲什麼分組沒有任何聚合函數? – jarlh

+0

對不起SQL Server 2014. – user3374841

+1

我認爲你正在尋找Pivot操作http://www.databasejournal.com/features/mssql/converting-rows-to-columns-pivot-and-columns-to-rows-unpivot-in -sql-server.html –

回答

1

正常工作這是一個沒有使用類似支點的解決方案。從所有用戶名,我只是建立一個逗號列表。這個例子不使用SQL但結果集,並提供想要的輸出:

Group1 ObjectA UserA, UserB, UserC 
Group2 ObjectA UserE, UserF, UserH 

我改名一些列名,以避免關鍵字衝突 這個SQL中有趣的部分是爲xmlpath中,這是使用率恕我直言,使用SQLServer提供逗號列表的方式。

select 
distinct 
group2, security, 
substring((select ', ' + user2 from table1 t 
    where t.group2=table1.group2 and t.security=table1.security 
    order by t.user2 
    for xml path('')), 3, 10000) as User_List 
from table1 

http://sqlfiddle.com/#!6/61b9b6/4

如果有另一個更好的辦法,SQLServer的2014之內,也許新的,我渴望傾聽。

+0

我同意'對於XML路徑'是一種適當的技術,但要小心包括'.value('。','varchar(max) ')'它從沒有XML的XML片段中檢索任何「特殊」字符的值。 –

0

我已經安裝下面的例子來說明

  1. 使用應用運算符與FOR XML PATH。我使用了一個外部應用程序,因爲有一個用戶不能訪問對象。
  2. 在下面的第一個查詢中,我在結果中避免了「XML實體」。請注意,對象名稱包含XML需要形成XML的字符。下面接着第二個查詢顯示,如果TYPE和.value的(......省略了會發生什麼

SQL Fiddle

MS SQL服務器2014架構設置

CREATE TABLE Users 
    ([Code] varchar(1), [UserName] varchar(4)) 
; 

INSERT INTO Users 
    ([Code], [UserName]) 
VALUES 
    ('A', 'Aaaa'), 
    ('B', 'Bbbb'), 
    ('C', 'Cccc'), 
    ('D', 'Dddd'), 
    ('E', 'Eeee') 
; 


CREATE TABLE Objects  
    ([Code] varchar(7), [Name] varchar(23)) 
; 

INSERT INTO Objects 
    ([Code], [Name]) 
VALUES 
    ('ObjectA', 'Fred & Ginger Whizzbang'), 
    ('ObjectB', 'The diamond<> cutter'), 
    ('ObjectC', 'Whatever'), 
    ('ObjectD', 'Blah de Blah') 
; 

CREATE TABLE ObjectAccess 
    ([ID] int, [ObjectCode] varchar(7), [UserCode] varchar(1)) 
; 

INSERT INTO ObjectAccess 
    ([ID], [ObjectCode], [UserCode]) 
VALUES 
    (1, 'ObjectA', 'A'), 
    (2, 'ObjectA', 'B'), 
    (3, 'ObjectA', 'C'), 
    (4, 'ObjectB', 'D'), 
    (5, 'ObjectB', 'A'), 
    (6, 'ObjectB', 'B'), 
    (7, 'ObjectB', 'C'), 
    (8, 'ObjectC', 'B'), 
    (9, 'ObjectC', 'C'), 
    (10, 'ObjectC', 'D'), 
    (11, 'ObjectD', 'C'), 
    (12, 'ObjectD', 'D'), 
    (13, 'ObjectE', 'A'), 
    (14, 'ObjectF', 'D') 
; 

查詢1

SELECT 
     Users.code 
    , Users.UserName 
    , oa.ObjectList 
FROM Users 
     OUTER APPLY (
      SELECT 
        STUFF 
        ((
         SELECT /* DISTINCT -- can be used here if required */ 
           ',' + Objects.Name 
         FROM ObjectAccess 
           INNER JOIN Objects ON ObjectAccess.ObjectCode = Objects.Code 
         WHERE ObjectAccess.UserCode = Users.Code 
         ORDER BY Objects.Name 
         FOR XML PATH (''), TYPE --<< nb!! 
       ) 
        .value('.', 'varchar(max)') --<< nb!! 
        , 1, 1, '') 
    ) AS oa (ObjectList) 

Results

| code | UserName |               ObjectList | 
|------|----------|--------------------------------------------------------------------| 
| A |  Aaaa |      Fred & Ginger Whizzbang,The diamond<> cutter | 
| B |  Bbbb |    Fred & Ginger Whizzbang,The diamond<> cutter,Whatever | 
| C |  Cccc | Blah de Blah,Fred & Ginger Whizzbang,The diamond<> cutter,Whatever | 
| D |  Dddd |       Blah de Blah,The diamond<> cutter,Whatever | 
| E |  Eeee |                (null) | 

查詢2

SELECT 
     Users.code 
    , Users.UserName 
    , oa.ObjectList 
FROM Users 
     OUTER APPLY (
      SELECT 
        STUFF 
        ((
         SELECT /* DISTINCT -- can be used here if required */ 
           ',' + Objects.Name 
         FROM ObjectAccess 
           INNER JOIN Objects ON ObjectAccess.ObjectCode = Objects.Code 
         WHERE ObjectAccess.UserCode = Users.Code 
         ORDER BY Objects.Name 
         FOR XML PATH ('') 
       ) 
        , 1, 1, '') 
    ) AS oa (ObjectList) 

Results

| code | UserName |                 ObjectList | 
|------|----------|------------------------------------------------------------------------------| 
| A |  Aaaa |      Fred &amp; Ginger Whizzbang,The diamond&lt;&gt; cutter | 
| B |  Bbbb |    Fred &amp; Ginger Whizzbang,The diamond&lt;&gt; cutter,Whatever | 
| C |  Cccc | Blah de Blah,Fred &amp; Ginger Whizzbang,The diamond&lt;&gt; cutter,Whatever | 
| D |  Dddd |        Blah de Blah,The diamond&lt;&gt; cutter,Whatever | 
| E |  Eeee |                  (null) |