2015-04-16 4 views
3

У меня есть запрос TSQL, с которым я пытаюсь объединить данные. Таблица содержит записи пользователей и ключи доступа, которые они хранят, такие как администратор сайта, модератор и т. Д. ПК находится на кнопке «Пользователь» и «Доступ», поскольку пользователь может существовать несколько раз с разными ключами.Группа TSQL по вопросам

Теперь я пытаюсь отобразить таблицу всех пользователей и в одном столбце, все ключи, которые пользователь держит.

Если у bob было три отдельные записи для трех его отдельных ключей доступа, результат должен иметь только одну запись для bob, при этом все три уровня доступа.

SELECT A.[FirstName], 
       A.[LastName], 
       A.[ntid], 
       A.[qid], 
       C.FirstName AS addedFirstName, 
       C.LastName AS addedLastName, 
       C.NTID AS addedNTID, 
       CONVERT(VARCHAR(100), p.TIMESTAMP, 101) AS timestamp, 
       (
        SELECT k.accessKey, 
          k.keyDescription 
        FROM TFS_AdhocKeys AS k 
        WHERE p.accessKey = k.accessKey 
        FOR  XML PATH ('key'), TYPE, ELEMENTS, ROOT ('keys') 
       ) 
     FROM  TFS_AdhocPermissions AS p 
     LEFT OUTER JOIN dbo.EmployeeTable as A 
     ON p.QID = A.QID 
     LEFT OUTER JOIN dbo.EmployeeTable AS C 
     ON p.addedBy = C.QID 
     GROUP BY a.qid 
     FOR  XML PATH ('data'), TYPE, ELEMENTS, ROOT ('root'); 
    END 

Я пытаюсь группировать данные по a.qid, но его заставляет меня группы на каждой колонке в избранных, которые затем не быть уникальным, так оно будет содержать дубликаты.

Что еще нужно сделать для этого?

В настоящее время:

UserID | accessKey 
123  | admin 
123  | moderator 

Желаемая:

UserID | accessKey 
123  | admin 
      moderator 
+0

Каждый столбец должен либо быть перечислены в GROUP BY или быть собраны с совокупной функции, но не оба. Обратите внимание, что один из ** MIN() ** и ** MAX() ** часто используется в качестве агрегатной функции для полей * char * и * varchar *. –

+0

Правильно, в значительной степени то, что ошибка сказала, что я получил, что я не знал, как настроить, для чего именно поэтому я разместил вопрос с просьбой о некоторых дополнительных указаниях – SBB

ответ

0

В последнее время я работал над чем-то и имел подобную проблему. Как и ваш запрос, у меня был внутренний «для xml» с объединениями во внешнем «для xml». Оказалось, что он работает лучше, если соединения были во внутреннем «для xml». Код будет вставлен ниже. Надеюсь, это поможет.

Select 
(Select Institution.Name, Institution.Id 
, (Select Course.Courses_Id, Course.Expires, Course.Name 
    From 
     (Select Course.Courses_Id, Course.Expires, Courses.Name 
     From Institutions Course Course Join Courses On Course.Courses_Id = Courses.Id 
     Where Course.Institutions_Id = 31) As Course 
     For Xml Auto, Type, Elements) As Courses 
    From Institutions Institution 
For Xml Auto, Elements, Root('Institutions')) 
0

Поскольку у меня нет определений для других таблиц, которые у меня есть, я просто делаю тестовые данные, и вы можете следовать этому, чтобы ответить на ваши вопросы.

Создать ЗАЯВЛЕНИЕ

CREATE TABLE #test(UserId INT, AccessLevel VARCHAR(20)) 

Вставка образец данных

INSERT INTO #test VALUES(123, 'admin') 
         ,(123, 'moderator') 
         ,(123, 'registered') 
         ,(124, 'moderator') 
         ,(124, 'registered') 
         ,(125, 'admin') 

С помощью ROW_NUMBER() вы можете добиться того, что вам нужно

;WITH C AS(
    SELECT ROW_NUMBER() OVER(PARTITION BY UserId ORDER BY UserId) As Rn 
      ,UserId 
      ,AccessLevel 
    FROM #test 
) 
SELECT CASE Rn 
      WHEN 1 THEN UserId 
      ELSE NULL 
     END AS UserId 
     ,AccessLevel 
FROM C 

Выход

UserId AccessLevel 
------ ----------- 
123  admin 
NULL moderator 
NULL registered 
124  moderator 
NULL registered 
125  admin 
Смежные вопросы