2013-08-01 3 views
2

Мне нужен совместимый с представлением запрос SQL для выполнения следующего результата (вид 1).Разделение результатов на отдельные столбцы

Table 1: 
-------------- 
ID | Folder 
-------------- 
1 | foo 
2 | bar 

Table 2: 
------------------------------------- 
ID | Table1_ID | Name | Right 
------------------------------------- 
1 | 1   | fooUser | W 
2 | 2   | barUser | R 

View 1: 
------------------------------- 
Folder | fooUser | barUser 
------------------------------- 
foo  |  W  | 
bar  |   | R 

Я был в состоянии сделать это только с помощью пользовательских функций, но я могу использовать это только как процедуры хранения. Я хочу привязать результат к GridView. Надеюсь, кто-нибудь может мне помочь.

+0

Если вы ожидаете, что это будет динамическим, когда третья строка добавляется в таблице 2 (и ожидая появления нового столбца), вы не собираетесь получать его из представления (или любого другого объекта, который может быть скомпонован в более крупные запросы) - запрос в представлении может быть только статическим запросом, и любой конкретный статический запрос всегда дает результаты с одна и та же «форма» - фиксированное количество столбцов с именами и типами данных этих столбцов. –

+0

Конечно, мне нужны динамические данные. Я знал, что моя попытка невозможна, потому что я не нашел возможного решения. Спасибо, что объяснил это мне. Dunno, если я должен создать новую тему, но я все равно спрошу: может ли Entity Framework выполнить эту задачу для меня? Или создает во время выполнения datatable наиболее распространенное решение? – Bonzai

ответ

2

В любое время, когда вы хотите преобразовать значения в столбцы, используйте PIVOT. Здесь вам понадобится выбрать:

SELECT Folder, [fooUser], [baruser] 
FROM (SELECT t.Folder, tt.* FROM one t JOIN two tt ON t.ID = tt.Table1_ID) AS source 
PIVOT 
(
    MAX(Rightt) 
    FOR Name IN (fooUser, barUser) 
) AS PivotTable; 

Применить его CREATE VIEW ... AS и он должен работать.

SQLFiddle

+0

Спасибо за ваше решение, но я забыл упомянуть, что речь идет о динамических данных. – Bonzai

0

Просто для удовольствия, вот глупый ответ, но это работает :) Я рекомендую использовать PIVOT хотя @makciook.

select a.Folder, 
     foo.[Right] fooUser, 
     bar.[Right] barUser 
    from one a 
    left join two foo on a.ID = 1 and foo.ID = 1 
    left join two bar on a.ID = 2 and bar.ID = 2 
2

Вы можете использовать агрегатную функцию с выражением CASE, чтобы повернуть данные из строк в столбцы:

select t1.folder, 
    max(case when t2.name = 'fooUser' then [right] else '' end) fooUser, 
    max(case when t2.name = 'barUser' then [right] else '' end) barUser 
from table1 t1 
inner join table2 t2 
    on t1.id = t2.Table1_ID 
group by t1.folder; 

См SQL Fiddle with Demo.

Если вам необходимо динамичное решение, то вам нужно будет использовать динамический SQL:

DECLARE @cols AS NVARCHAR(MAX), 
    @query AS NVARCHAR(MAX) 

select @cols = STUFF((SELECT distinct ',' + QUOTENAME(Name) 
        from table2 
      FOR XML PATH(''), TYPE 
      ).value('.', 'NVARCHAR(MAX)') 
     ,1,1,'') 

set @query = 'SELECT folder, ' + @cols + ' 
      from 
      (
       select t1.folder, 
       t2.name, t2.[right] 
       from table1 t1 
       inner join table2 t2 
       on t1.id = t2.Table1_ID 
      ) x 
      pivot 
      (
       max([right]) 
       for name in (' + @cols + ') 
      ) p ' 

execute(@query); 

См SQL Fiddle with Demo

+0

Поскольку мне нужны динамические данные, я не могу использовать ваше решение. Но я хотел бы знать разницу в скорости между вашим решением и одним из @makciook – Bonzai

+0

@Bonzai См. Мое редактирование, я добавил динамическое SQL-решение. – Taryn

+0

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

Смежные вопросы