2013-02-14 23 views
5

मेरे पास निम्न तालिका:एसक्यूएल सर्वर pivots ... मैं आदेश प्रकार की एक श्रृंखला के लिए पिछले पांच आदेश दिखा सकते हैं

create table myorders(ordertype char(1), orderdate datetime, orderid int) 

इस तालिका में निम्न डेटा है:

insert into myorders(ordertype, orderdate, orderid) values('P', '2013-02-14 20:04:48:287', 11082360) 
insert into myorders(ordertype, orderdate, orderid) values('P', '2013-02-14 20:02:40:407', 40087130) 
insert into myorders(ordertype, orderdate, orderid) values('P', '2013-02-14 20:02:07:277', 7990558) 
insert into myorders(ordertype, orderdate, orderid) values('C', '2013-02-14 19:58:46:097', 8225181) 
insert into myorders(ordertype, orderdate, orderid) values('P', '2013-02-14 19:58:39:740', 40087129) 
insert into myorders(ordertype, orderdate, orderid) values('C', '2013-02-14 19:57:33:063', 8225235) 
insert into myorders(ordertype, orderdate, orderid) values('C', '2013-02-14 19:56:17:207', 8225233) 
insert into myorders(ordertype, orderdate, orderid) values('C', '2013-02-14 19:54:50:630', 8225232) 
insert into myorders(ordertype, orderdate, orderid) values('P', '2013-02-14 19:48:07:300', 11082337) 
insert into myorders(ordertype, orderdate, orderid) values('P', '2013-02-14 19:47:49:997', 40087128) 
insert into myorders(ordertype, orderdate, orderid) values('P', '2013-02-14 19:46:40:667', 40087127) 
insert into myorders(ordertype, orderdate, orderid) values('C', '2013-02-14 19:45:32:550', 8225231) 
insert into myorders(ordertype, orderdate, orderid) values('P', '2013-02-14 19:45:11:203', 11082326) 
insert into myorders(ordertype, orderdate, orderid) values('C', '2013-02-14 19:44:57:990', 8225230) 
insert into myorders(ordertype, orderdate, orderid) values('P', '2013-02-14 19:43:52:953', 40087126) 
insert into myorders(ordertype, orderdate, orderid) values('C', '2013-02-14 19:43:20:853', 8225229) 
insert into myorders(ordertype, orderdate, orderid) values('P', '2013-02-14 19:41:33:740', 11082319) 
insert into myorders(ordertype, orderdate, orderid) values('C', '2013-02-14 19:41:19:853', 8225228) 
insert into myorders(ordertype, orderdate, orderid) values('P', '2013-02-14 19:40:33:127', 40087125) 
insert into myorders(ordertype, orderdate, orderid) values('P', '2013-02-14 19:40:25:537', 40087124) 

डेटा इस तरह दिखता है:

OrderType OrderDate     OrderId 
-------- -----------------------  --------- 
P  2013-02-14 20:04:48.287 11082360 
P  2013-02-14 20:02:40.407 40087130 
P  2013-02-14 20:02:07.277 7990558 
C  2013-02-14 19:58:46.097 8225181 
P  2013-02-14 19:58:39.740 40087129 
C  2013-02-14 19:57:33.063 8225235 
C  2013-02-14 19:56:17.207 8225233 
C  2013-02-14 19:54:50.630 8225232 
P  2013-02-14 19:48:07.300 11082337 
P  2013-02-14 19:47:49.997 40087128 
P  2013-02-14 19:46:40.667 40087127 
C  2013-02-14 19:45:32.550 8225231 
P  2013-02-14 19:45:11.203 11082326 
C  2013-02-14 19:44:57.990 8225230 
P  2013-02-14 19:43:52.953 40087126 
C   2013-02-14 19:43:20.853 8225229 
P  2013-02-14 19:41:33.740 11082319 
C  2013-02-14 19:41:19.853 8225228 
P  2013-02-14 19:40:33.127 40087125 
P  2013-02-14 19:40:25.537 40087124 

मैं डेटा पिवट करने के लिए तो यह इस तरह दिखता है चाहते हैं:

C_LastFiveOrders C_OrderDate     P_LastFiveOrders P_OrderDate 
---------------- -----------------------  ---------------- ----------------------- 
8225181   2013-02-14 19:58:46.097  11082360   2013-02-14 20:04:48.287 
8225235   2013-02-14 19:57:33.063  40087130   2013-02-14 20:02:40.407 
8225233   2013-02-14 19:56:17.207  7990558   2013-02-14 20:02:07.277 
8225232   2013-02-14 19:54:50.630  40087129   2013-02-14 19:58:39.740 
8225231   2013-02-14 19:45:32.550  11082337   2013-02-14 19:48:07.300 

ध्यान दें कि आदेश आदेश में ऑर्डरडेट द्वारा क्रमबद्ध किए गए हैं।

मैं अतिरिक्त ऑर्डर टाइप जोड़ने में सक्षम होना चाहता हूं। मैं अंतिम एक्स ऑर्डर देखने के लिए लचीलापन भी पसंद करूंगा। नमूने में मैं पिछले पांच ऑर्डर देख रहा हूं। मैं पिछले 10 या 20 ऑर्डर देखने में सक्षम होना चाहता हूं।

+3

+1 परीक्षण तालिका और डेटा सेटअप के लिए! – Bryan

+1

-1 कुछ भी कोशिश नहीं करने के लिए! – Kermit

+0

मुझे वह चाहिए।मैं ब्लूफेट की तरह एक पिवोट गुरु बनने जा रहा हूं। वे मुझे पिवोट केन एलओएल कहने जा रहे हैं। मुझे स्क्रॉल 3-व्हील-क्रांति बनाने के लिए – codingguy3000

उत्तर

4

यह कई अलग-अलग तरीकों से किया जा सकता है। मामले के साथ

कुल योग: आप एक CASE अभिव्यक्ति के साथ एक समग्र समारोह का उपयोग कर सकते हैं:

select 
    max(case when ordertype = 'c' then orderid end) C_LASTFIVEORDERS, 
    max(case when ordertype = 'c' then orderdate end) C_ORDERDATE, 
    max(case when ordertype = 'p' then orderid end) P_LASTFIVEORDERS, 
    max(case when ordertype = 'p' then orderdate end) P_ORDERDATE 
from 
(
    select orderid, ordertype, orderdate, rn 
    from 
    (
    select orderid, ordertype, orderdate, 
     row_number() over(partition by ordertype 
         order by orderdate desc) rn 
    from myorders 
) src 
    where rn <=5 
) s 
group by rn 

SQL Fiddle with Demo देखें।

एकाधिक शामिल: आप अपनी तालिका पर कई बार शामिल हो सकते हैं:

;with cte as 
(
    select orderid, ordertype, orderdate, 
     row_number() over(partition by ordertype 
         order by orderdate desc) rn 
    from myorders 
) 
select 
    c1.orderid C_LASTFIVEORDERS, 
    c1.orderdate C_ORDERDATE, 
    c2.orderid P_LASTFIVEORDERS, 
    c2.orderdate P_ORDERDATE 
from cte c1 
left join cte c2 
    on c1.rn = c2.rn 
    and c2.ordertype = 'P' 
where c1.rn <=5 
    and c1.ordertype = 'C' 

देखें SQL Fiddle with Demo

स्टेटिक धुरी:

अंत में, आप दोनों UNPIVOT और लागू कर सकते हैं परिणाम प्राप्त करने के लिए PIVOT फ़ंक्शन:

select C_LastFiveOrders, C_orderdate, 
    P_LastFiveOrders, P_orderdate 
from 
(
    select rn, 
    case 
     when col = 'orderid' then ordertype+'_LastFiveOrders' 
     else ordertype+'_'+col end col_name, 
    value 
    from 
    (
    select ordertype, 
     convert(varchar(50), orderdate, 121) orderdate, 
     cast(orderid as varchar(50)) orderid, 
     row_number() over(partition by ordertype 
         order by orderdate desc) rn 
    from myorders 
)src 
    unpivot 
    (
    value 
    for col in (orderdate, orderid) 
) un 
    where rn <= 5 
) s 
pivot 
(
    max(value) 
    for col_name in (C_LastFiveOrders, C_orderdate, 
        P_LastFiveOrders, P_orderdate) 
) piv 

SQL Fiddle with Demo देखें।

गतिशील धुरी:

अपने OrderType मूल्यों अज्ञात हैं, तो आप गतिशील एसक्यूएल का उपयोग कर सकते हैं:

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

select @cols = STUFF((SELECT distinct ',' + QUOTENAME(ordertype +c.col) 
         from myorders 
         cross apply 
         (
         select '_LastFiveOrders' col 
         union all 
         select '_OrderDate' 
        ) c 
      FOR XML PATH(''), TYPE 
      ).value('.', 'NVARCHAR(MAX)') 
     ,1,1,'') 


set @query 
    = 'SELECT ' + @cols + ' 
    from 
    (
     select rn, 
     case 
      when col = ''orderid'' then ordertype+''_LastFiveOrders'' 
      else ordertype+''_''+col end col_name, 
     value 
     from 
     (
     select ordertype, 
      convert(varchar(50), orderdate, 121) orderdate, 
      cast(orderid as varchar(50)) orderid, 
      row_number() over(partition by ordertype 
          order by orderdate desc) rn 
     from myorders 
    )src 
     unpivot 
     (
     value 
     for col in (orderdate, orderid) 
    ) un 
     where rn <= 5 
    ) s 
    pivot 
    (
     max(value) 
     for col_name in (' + @cols + ') 
    ) p 
    ' 

execute(@query) 

देखें SQL Fiddle with Demo

सभी प्रश्नों परिणाम दे:

| C_LASTFIVEORDERS |    C_ORDERDATE | P_LASTFIVEORDERS |    P_ORDERDATE | 
------------------------------------------------------------------------------------------- 
|   8225181 | 2013-02-14 19:58:46.097 |   11082360 | 2013-02-14 20:04:48.287 | 
|   8225235 | 2013-02-14 19:57:33.063 |   40087130 | 2013-02-14 20:02:40.407 | 
|   8225233 | 2013-02-14 19:56:17.207 |   7990558 | 2013-02-14 20:02:07.277 | 
|   8225232 | 2013-02-14 19:54:50.630 |   40087129 | 2013-02-14 19:58:39.740 | 
|   8225231 | 2013-02-14 19:45:32.550 |   11082337 | 2013-02-14 19:48:07.300 | 
+0

+1। – Kermit

+0

@njk क्षमा करें मैं खुद की मदद नहीं कर सकता – Taryn

+0

आप जीतते हैं यह गतिशील एसक्यूएल संस्करण के साथ एकमात्र मुद्दा है कि कॉलम क्रम में नहीं हैं। – codingguy3000

2

यह काम कर सकते हैं:

;WITH myorders_CTE AS 
    (
    SELECT ordertype, orderdate, orderid, 
    row_number() over (partition BY ordertype ORDER BY orderdate DESC) AS sequence 
    FROM myorders 
) 

SELECT c.orderid AS C_LastFiveOrders, c.orderdate AS C_OrderDate, 
    p.orderid AS P_LastFiveOrders, p.orderdate AS P_OrderDate 
FROM myorders_CTE c 
JOIN myorders_CTE p ON c.sequence = p.sequence 
WHERE c.ordertype = 'C' 
    AND p.ordertype = 'P' 
    AND c.sequence <= 5 
    AND p.sequence <= 5 
ORDER BY c.sequence 

यह एक आत्म में शामिल होने का उपयोग करता है, लेकिन धुरी का उपयोग नहीं करता।