EDIT: 11:26 PST. Я думаю, вам нужен динамический SQL, чтобы делать то, что вы хотите. Поскольку вы делаете сложный набор блоков, который вы добавляете по столбцу и повторяете имена столбцов.
declare @Temp table ([No] int, [Add] varchar(4), Member varchar(4), Det1 char, Det2 char, Det3 char, Det4 char);
insert into @Temp values
(1, 'Add1', 'Dad1', 'q','w','e','r'),
(1, 'Add1', 'Mom1', 'q','w','e','r'),
(1, 'Add1', 'Chd1', 'q','w','e','r'),
(1, 'Add1', 'Chd1', 'q','w','e','r'),
(1, 'Add2', 'Mom2', 'q','w','e','r'),
(1, 'Add2', 'Chd2', 'q','w','e','r'),
(1, 'Add2', 'Chd2', 'q','w','e','r')
if object_id('tempdb..#Temp') is not null
drop table #temp
select
No
, [Add]
, Member
, Det1
, Det2
, Det3
, Det4
, dense_rank() over(order by [Add]) as part
, row_number() over(partition by [Add] order by Member) as rwn
into #Temp
from @Temp
declare
@Cursor int = 1
, @Max int
, @Addendum varchar(max) = ''
, @NL char = char(10)
, @SQL nvarchar(max)
, @Part int
;
-- set up my loop prep
-- statement to execute later
select @SQL = 'Select No, [Add] ' + @NL + 'from #Temp' + @NL + 'group by No, [Add]';
-- max iteration of an occurence
Select @Max = max(rwn) from #Temp
-- ensure we use the part that has the max occurrence, less we get less results than we need
Select @Part = max(part) from #Temp where rwn = @Max
-- While the statement is looping it is adding to itself dynamically to select your values. I could do a loop of a loop
-- to get only certain values you want too, but this is enough for an example. EG, set a bit for Det1, Det2 and then make a statement for those things too.
While @Cursor <= @Max
BEGIN
Select @Addendum += @NL + ', max(case when rwn = ' + cast(@Cursor as varchar) + ' then Member end) as Member ' +
@NL + ', max(case when rwn = ' + cast(@Cursor as varchar) + ' then Det1 end) as Det1 ' +
@NL + ', max(case when rwn = ' + cast(@Cursor as varchar) + ' then Det2 end) as Det2 ' +
@NL + ', max(case when rwn = ' + cast(@Cursor as varchar) + ' then Det3 end) as Det3 ' +
@NL + ', max(case when rwn = ' + cast(@Cursor as varchar) + ' then Det4 end) as Det4 '
from #Temp where part = @Part and rwn = @Cursor
Select @Cursor += 1;
END
-- 'stuff' is a sql syntax to insert in a specific place a chunk of something.
Select @SQL = stuff(@SQL, charindex('from', @SQL), 0, @Addendum + @NL);
-- I want to now 'execute' the statement I just built up in memory to select what I need
exec sp_executesql @SQL
Похоже, вы просто делаете сложную группировку, но я не уверен, из вашего примера, если вы желаете, чтобы явно оставить некоторые из ваших членов. Это будет работать как на SQL Server 2008 и выше, как:
declare @Temp table ([No] int, [Add] varchar(4), Member varchar(4), Det1 char, Det2 char, Det3 char, Det4 char);
insert into @Temp values
(1, 'Add1', 'Dad1', 'q','w','e','r'),
(1, 'Add1', 'Mom1', 'q','w','e','r'),
(1, 'Add1', 'Chd1', 'q','w','e','r'),
(1, 'Add1', 'Chd1', 'q','w','e','r'),
(1, 'Add2', 'Mom2', 'q','w','e','r'),
(1, 'Add2', 'Chd2', 'q','w','e','r'),
(1, 'Add2', 'Chd2', 'q','w','e','r')
Select *
from @Temp
select
No
, [Add]
, Member
, max(Det1) as Det1
, max(Det2) as Det2
, max(Det3) as Det3
, max(Det4) as Det4
from @Temp
group by No, [Add], Member
процедура А «Pivot» хорош для принятия множества значений, которые обычно ассоциируются с одним значением «типа». Это хорошо для вещей, которые представляют собой несколько строк для значений поиска.
Как у вас есть человек, и они связаны с таблицей заказов и заказ столик имеет столбец типа, который связан с таблицей перекодировки, которая является ключевой таблицей пары как
1 = рубашка, 2 = брюки , 3 = ботинки, 4 = носки, 5 = ремень, 6 = шляпа, 7 = часы и т. Д.
Вы можете сделать поворот для нескольких вещей простым прохождением левого соединения и выражением типа " вы хотите отступить. EG:
from person p
left join order o1 on p.personid = o1.personid and o1.type = 1
left join order o2 on p.personid = o2.personid and o2.type = 2
Там нет правила в двигателе, который заявляет вы можете присоединиться только таблицу только один раз, так что если я указываю вам присоединиться в отношениях и конкретно определенный тип, я могу оценить мой выбор так:
Select p.PersonName, o1.Value, o2.Value
Обычно Pivot используется, когда у вас есть целая куча типов, и вы не хотите делать несколько левых объединений. Когда вы выполняете набор последовательностей, которые вы хотите сгруппировать, вам действительно нужно сделать «группу» для простых наборов. Я мог бы сделать это путем:
- стандартная группа по перечисленным выше, где каждый столбец в «группе» контролирует поток, а затем делает агрегат («макс», использованный выше), чтобы найти только одно значение максимальное появление этой группировки. Если ваши No, Add и Member будут иметь одно значение, это означает, что это работает.
макс (случай, когда то заканчивается) заявление, которое делает группировку для меня в выражении, как показано ниже:
Выберите у.PersonName , макс (случай, когда КодЗаказ = 1, то OrderAmount конца) , макс (случай, когда КодЗаказ = 2, то OrderAmount конца) , макс (случай, когда КодЗаказ = 3, то OrderAmount конца) от @Person у присоединиться к @Orders х on x.PersonId = y.PersonId group by PersonName
Оконные функции, которые дают мне возможность динамической группировки без предложения «group by».
Выберите y.PersonName , OrderAmount , row_number() над (раздел по PersonName порядке по OrderAmount) orderbyAmount , row_number() над (раздел по PersonName порядке по убыванию) OrderAmount orderbyAmountDesc , не более (случай, когда OrderID = 1, затем OrderAmount end) over (partition by PersonName)
, max (в случае, когда OrderID = 2, а затем OrderAmount end) over (partition by PersonName) , max (в случае, когда OrderID = 3, затем OrderAmount end) over (partition by PersonName) от @Person y присоединиться к @Orders x на x.PersonId = y.PersonI d
Это дает мне гибкость, если кому-то нужен какой-то сумасшедший отчет, в котором перечисляется второе или последнее появление чего-либо сложным процессом.
Я думаю, что стержень будет лучше для того, что вы пытаетесь сделать. – Jenn
То, что вы пытаетесь сделать, называется PIVOTing запроса. Но ваш случай немного сложнее, потому что, если я понимаю, вы хотите установить свой набор результатов в две колонки. И ваш желаемый результат не подходит к реестрам, которые вы предоставляете в качестве примера. –
Вам нужна динамическая перекрестная вкладка. Пейнт не будет работать, потому что у вас есть несколько агрегатов. Взгляните на эту статью, в которой объясняется, как это сделать. http://www.sqlservercentral.com/articles/Crosstab/65048/ –