TSQL धुरी कुल समारोह के बिना


139

मेरे पास इस तरह की एक तालिका है ...

CustomerID   DBColumnName   Data
--------------------------------------
1            FirstName      Joe
1            MiddleName     S
1            LastName       Smith
1            Date           12/12/2009
2            FirstName      Sam
2            MiddleName     S
2            LastName       Freddrick
2            Date           1/12/2009
3            FirstName      Jaime
3            MiddleName     S
3            LastName       Carol
3            Date           12/1/2009

और मुझे यह चाहिए ...

क्या PIVOT का उपयोग करना संभव है?

CustomerID  FirstName   MiddleName          LastName        Date
----------------------------------------------------------------------
1           Joe             S               Smith           12/12/2009
2           Sam             S               Freddrick       1/12/2009
3           Jaime           S               Carol           12/1/2009

जवाबों:


102

आप MAX समुच्चय का उपयोग कर सकते हैं, यह अभी भी काम करेगा। एक मान का MAX = वह मान ..

इस मामले में, आप ग्राहक पर 5 बार स्वयं शामिल हो सकते हैं, dbColumnName प्रति तालिका संदर्भ द्वारा फ़िल्टर करें। यह बेहतर तरीके से काम कर सकता है।


1
अगर आपके पास पहले नाम के साथ 2 पोशाक हैं
लियोनार्डो

1
वह काम करेगा। याद रखें कि DBColumnName मेटाडेटा है - आप सचमुच "CustomerID = 1 और DBColumnName = 'FirstName' द्वारा फ़िल्टर करते हैं। बेशक, यह टूट जाता है अगर आपके पास दिए गए CustomerID के लिए कई FirstName पंक्तियाँ हैं, लेकिन यदि आप अपनी तालिकाओं को ठीक से बना रहे हैं तो दोनों CustomerID और DBColumnName आपकी प्राथमिक कुंजी का हिस्सा हैं ...
4AM

7
एक उदाहरण के रूप में कुछ कोड / मज़ाक महान होगा और इस जवाब को पूरी तरह से पूरा कर दिया।
डेविडशेकर

167

हां लेकिन क्यों !!??

   Select CustomerID,
     Min(Case DBColumnName When 'FirstName' Then Data End) FirstName,
     Min(Case DBColumnName When 'MiddleName' Then Data End) MiddleName,
     Min(Case DBColumnName When 'LastName' Then Data End) LastName,
     Min(Case DBColumnName When 'Date' Then Data End) Date
   From table
   Group By CustomerId

2
^ ^ यह मेरे लिए काम किया। PIVOT गैर-संख्यात्मक मानों के लिए कुशल नहीं है।
डायनेक्स

6
यह एक बेहतरीन विकल्प है। मैं Pivotअपनी क्वेरी में उपयोग कर रहा था , फिर मैंने इस पर स्विच किया और दोनों को एक साथ चलाने के लिए निष्पादन योजना को देखा। इस दृष्टिकोण की लागत and% थी और धुरी के दृष्टिकोण ने ९ २% लिया!
mafue

2
@CharlesBretana, आप महान हैं! तुमने मेरी आत्मा को बचा लिया! ) यह सबसे अच्छा समाधान है। धन्यवाद!
चौकी_ब्लैक

3
वास्तव में इस समाधान से प्यार है, यह भी सुनिश्चित करता है कि कॉलम में पिवट एक के बजाय सही डेटा हो, धन्यवाद!
टेनरेज़ा

2
यह महान काम! लेकिन मैं कैसे रोकूँ -Warning: Null value is eliminated by an aggregate or other SET operation
GiddyUpHorsey

24
WITH pivot_data AS
(
SELECT customerid, -- Grouping Column
dbcolumnname, -- Spreading Column
data -- Aggregate Column
FROM pivot2 
)
SELECT customerid, [firstname], [middlename], [lastname]
FROM pivot_data
PIVOT (max(data) FOR dbcolumnname IN ([firstname],[middlename],[lastname])) AS p;

3
यह स्वीकृत उत्तर होना चाहिए क्योंकि यह TSQL पिवट कमांड के उचित उपयोग को दर्शाता है।
Ubercoder

1
यह ध्यान देने योग्य है कि इस क्वेरी में, "pivot2" उस तालिका का नाम है जिसमें मूल डेटा रहता है। साथ ही, CTE का यहाँ उपयोग अतिश्योक्तिपूर्ण है - SELECTCTE के नीचे दिए गए बयान में मूल तालिका का नाम निर्दिष्ट किया जा सकता है।
STLDev

@STLDev वास्तव में STLDev कि धुरी कैसे काम करती है। हम तालिका "pivot2" में सभी कॉलम नहीं जानते हैं। वास्तव में, अन्य स्तंभ हो सकते हैं, ओपी ने यह निर्दिष्ट नहीं किया कि तालिका में हैं। इसलिए जब तक आप स्तंभों को प्रतिबंधित नहीं करते हैं - CTE या व्युत्पन्न तालिका क्वेरी का उपयोग करते हैं - तब तालिका में सभी स्तंभ समूह में उपयोग किए जाते हैं। दूसरे शब्दों में, PIVOT कुछ देता है, लेकिन वह नहीं जिसकी हम उम्मीद करते हैं। यह एक अवधारणा है जिसमें 70-761 प्रमाणन परीक्षा के लिए गहराई से कवर किया गया है।
ज़र्कोलोट

2
यह ध्यान देने योग्य है कि PIVOT स्वचालित रूप से उन समूहों द्वारा समूह बनाता है जो कभी PIVOT में उपयोग नहीं किए जाते हैं। इसलिए इस उदाहरण में [डेटा] और [dbcolumnname] PIVOT में हैं, इसलिए सब कुछ [CustomerId]
Sal

9
SELECT
main.CustomerID,
f.Data AS FirstName,
m.Data AS MiddleName,
l.Data AS LastName,
d.Data AS Date
FROM table main
INNER JOIN table f on f.CustomerID = main.CustomerID
INNER JOIN table m on m.CustomerID = main.CustomerID
INNER JOIN table l on l.CustomerID = main.CustomerID
INNER JOIN table d on d.CustomerID = main.CustomerID
WHERE f.DBColumnName = 'FirstName' 
AND m.DBColumnName = 'MiddleName' 
AND l.DBColumnName = 'LastName' 
AND d.DBColumnName = 'Date' 

संपादित करें: मैंने इसे एक संपादक के बिना लिखा है और SQL नहीं चलाया है। मुझे उम्मीद है, आपको यह विचार मिलेगा।


9

ठीक है, गरीब प्रश्न के लिए खेद है। gbn मुझे सही रास्ते पर ले गई। यह वही है जो मैं एक उत्तर में देख रहा था।

SELECT [FirstName], [MiddleName], [LastName], [Date] 
FROM #temp 
PIVOT
(   MIN([Data]) 
    FOR [DBColumnName] IN ([FirstName], [MiddleName], [LastName], [Date]) 
)AS p

फिर मुझे कुछ समय के स्टेटमेंट का उपयोग करना था और उपरोक्त स्टेटमेंट को एक varchar के रूप में बनाना और dynmaic sql का उपयोग करना था।

कुछ इस तरह का उपयोग करना

SET @fullsql = @fullsql + 'SELECT ' + REPLACE(REPLACE(@fulltext,'(',''),')','')
SET @fullsql = @fullsql + 'FROM #temp '
SET @fullsql = @fullsql + 'PIVOT'
SET @fullsql = @fullsql + '('
SET @fullsql = @fullsql + ' MIN([Data])'
SET @fullsql = @fullsql + ' FOR [DBColumnName] IN '+@fulltext
SET @fullsql = @fullsql + ')'
SET @fullsql = @fullsql + 'AS p'

EXEC (@fullsql)

थोड़ी देर लूप का उपयोग करके @fulltext का निर्माण करने के लिए और तालिका से अलग कॉलम नामों का चयन करें। जवाब के लिए धन्यवाद।


6

ओपी को वास्तव में तड़प के बिना धुरी की जरूरत नहीं थी, लेकिन आप में से जो यह देखने के लिए यहां आ रहे हैं:

sql पैरामीटरेट की गई cte क्वेरी

उस प्रश्न के उत्तर में एक ऐसी स्थिति शामिल है जहां एकत्रीकरण के बिना धुरी की आवश्यकता होती है इसलिए ऐसा करने का एक उदाहरण समाधान का हिस्सा है।


1

इसे इस्तेमाल करे:

SELECT CUSTOMER_ID, MAX(FIRSTNAME) AS FIRSTNAME, MAX(LASTNAME) AS LASTNAME ...

FROM
(

SELECT CUSTOMER_ID, 
       CASE WHEN DBCOLUMNNAME='FirstName' then DATA ELSE NULL END AS FIRSTNAME,
       CASE WHEN DBCOLUMNNAME='LastName' then DATA ELSE NULL END AS LASTNAME,
        ... and so on ...
GROUP BY CUSTOMER_ID

) TEMP

GROUP BY CUSTOMER_ID

1

यह काम करना चाहिए:

select * from (select [CustomerID]  ,[Demographic] ,[Data]
from [dbo].[pivot]
) as Ter

pivot (max(Data) for  Demographic in (FirstName, MiddleName, LastName, [Date]))as bro

1

धुरी क्वेरी के लिए गतिशील फ़ील्ड बनाने का एक शानदार तरीका यहाँ दिया गया है:

- एक tmp तालिका में मानों को संक्षिप्त करें

declare @STR varchar(1000)
SELECT  @STr =  COALESCE(@STr +', ', '') 
+ QUOTENAME(DateRange) 
from (select distinct DateRange, ID from ##pivot)d order by ID

--- उत्पन्न क्षेत्रों को देखें

print @STr

exec('  .... pivot code ...
pivot (avg(SalesAmt) for DateRange IN (' + @Str +')) AS P
order by Decile')
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.