2009-06-03 25 views
14

Sütunlara döndürülmesi gereken birden fazla satırın bulunduğu bir tabloyla çalışıyorum. Yani pivot bunun için mükemmel bir çözümdür ve ihtiyacım olan tek şey bir alan olduğunda iyi çalışır. Pivotu temel alan birkaç alanın geri dönmesine ihtiyacım var. İşte özellikleri ile sahte kod dışında çıkartılır:T-SQL'de Çoklu Sütun Pivotu

SELECT 
    field1, 
    [1], [2], [3], [4] 
FROM 
    (
    SELECT 
    field1, 
    field2, 
    (ROW_NUMBER() OVER(PARTITION BY field1 ORDER BY field2)) RowID 
    FROM tblname 
) AS SourceTable 
PIVOT 
    (
    MAX(field2) 
    FOR RowID IN ([1], [2], [3], [4]) 
) AS PivotTable; 

yukarıdaki sözdizimi zekice çalışır, ancak ben ilave bilgi alan3, Field4 bulunan almak gerektiğinde ne yapacağım ....?

+2

Tam olarak neye sahip olmanız gerekir? –

+0

Denedim, benim için iyi çalışıyor (blogda 3. yaklaşım). http://dba.stackexchange.com/questions/65786/query-pivot-multiple-columns-variable-number-of-rows – JayaPrakash

cevap

11

MAX kullanarak yeniden yaz (DURUM ...) ve GRUP:

select 
    field1 
, [1] = max(case when RowID = 1 then field2 end) 
, [2] = max(case when RowID = 2 then field2 end) 
, [3] = max(case when RowID = 3 then field2 end) 
, [4] = max(case when RowID = 4 then field2 end) 
from (
    select 
    field1 
    , field2 
    , RowID = row_number() over (partition by field1 order by field2) 
    from tblname 
) SourceTable 
group by 
    field1 

Oradan

+0

Yaptığım şey, ek bir ölçütle katıldığım bu tür tabloyu doldurmak için CTE'de CASe ifadeleri kullanmaktı. ----------------------- – websch01ar

+0

cteSec ile olduğu gibi ( \t \t vSec.ID SEÇ, \t --Secretary 1: İşte CTE olduğunu - \t MAX ( \t \t ÖRNEK vSec.RowID \t \t 1 ise vSec.field1 ELSE \t \t ' \t \t END \t) [SEC_OfficePhone1] \t MAX ( \t \t CASE vSec.RowID \t \t WHEN 1 THEN vSec.ELSE field2 \t \t ' \t \t END \t) [SEC_OfficeFax1] \t DAN \t \t \t Üstteki yüzde 100 \t ( \t --Bu iç sorgu (bu sekreter satır atar OLACAK) \t alan 1, alan 2, ID (vs.ID SİPARİŞ İLE vs.ID2 İLE ROW_NUMBER() ÜZERİNDE (bölme))vs tblname DAN \t rowID \t \t vs.ID TARAFINDAN 0 \t SİPARİŞ, Kimlik2 \t) \t vSec.ID ) – websch01ar

+0

TARAFINDAN Vsec \t GRUP Yani bu yöntemle ben bekliyorum sütun sayısını kodlanmış olması. Genel olarak bunu değişime bağlı olarak dinamik olarak yapmayı tercih ederim. Ama bir şirket olarak, havai fişe indirgemeye odaklanıyoruz, bu yüzden patron başına dört sekreterden daha fazlasına ihtiyaç duymadım ... Senden bana kredi verdim çünkü emriniz beni 20 davayı yazmaya götürdü ifadeleri. Bu, alt saniye yanıtı olan bir çekicilik gibi çalışır. – websch01ar

1

MS SQL Server kullanıyorsanız, ancak emin değilseniz ... Motorun CROSS APPLY işlevine bir göz atmak isteyebilirsiniz. Temel olarak, bir sonuç kümesine tablo değerli UDF sonuçlarını uygulamanıza izin verecektir. Bu, pivot sorgunuzu tablo değerli bir sonuç kümesine koymanızı gerektirir. BY

http://weblogs.sqlteam.com/jeffs/archive/2007/10/18/sql-server-cross-apply.aspx

+0

-1 Soru – Andomar

+0

ile ilişki göremiyor Soru etiketli ve T-SQL olarak adlandırılmış . Bu MS lehçesi .... – RolandTumble

+0

Ayrıca Sybase diyalektidir. –

1

vb alan3, Field4 eklemek ile sql deyimi sarabilirsiniz gibi bir şey:

select a.segment, sum(field2), sum(field3) 
from (original select with case arguments) a 
group by a.segment 

Sonuçlarınızı bir satırda daraltmalı, field1 üzerinde gruplandırılmış.

1

bir ROW_NUMBER üzerinden birden pivotlar yapmaya hile dizisi ve saha sayınız da saklamak için o satır numarası sırasını değiştirmektir. İşte size birden fazla PIVOT ifadesi ile ne yapmak istediğinizi gösteren bir örnek.

-- populate some test data 
if object_id('tempdb..#tmp') is not null drop table #tmp 
create table #tmp (
    ID int identity(1,1) not null, 
    MainField varchar(100), 
    ThatField int, 
    ThatOtherField datetime 
) 

insert into #tmp (MainField, ThatField, ThatOtherField) 
select 'A', 10, '1/1/2000' union all 
select 'A', 20, '2/1/2000' union all 
select 'A', 30, '3/1/2000' union all 
select 'B', 10, '1/1/2001' union all 
select 'B', 20, '2/1/2001' union all 
select 'B', 30, '3/1/2001' union all 
select 'B', 40, '4/1/2001' union all 
select 'C', 10, '1/1/2002' union all 
select 'D', 10, '1/1/2000' union all 
select 'D', 20, '2/1/2000' --union all 

-- pivot over multiple columns using the 1.1, 1.2, 2.1, 2.2 sequence trick 
select 
    MainField, 
    max([1.1]) as ThatField1, 
    max([1.2]) as ThatOtherField1, 
    max([2.1]) as ThatField2, 
    max([2.2]) as ThatOtherField2, 
    max([3.1]) as ThatField3, 
    max([3.2]) as ThatOtherField3, 
    max([4.1]) as ThatField4, 
    max([4.2]) as ThatOtherField4 
from 
    (
     select x.*, 
      cast(row_number() over (partition by MainField order by ThatField) as varchar(2)) + '.1' as ThatFieldSequence, 
      cast(row_number() over (partition by MainField order by ThatField) as varchar(2)) + '.2' as ThatOtherFieldSequence 
     from #tmp x 
    ) a 
    pivot (
     max(ThatField) for ThatFieldSequence in ([1.1], [2.1], [3.1], [4.1]) 
    ) p1 
    pivot (
     max(ThatOtherField) for ThatOtherFieldSequence in ([1.2], [2.2], [3.2], [4.2]) 
    ) p2 
group by 
    MainField 
İlgili konular