मैं इस समस्या को हल करने के लिए कुछ और अधिक विस्तृत कदम उठाने जा रहा हूँ। मैं माफी माँगता हूँ अगर यह बहुत लंबा है।
मैं आपके द्वारा दिए गए आधार के साथ शुरुआत करूँगा और इसका इस्तेमाल कुछ शब्दों को परिभाषित करने के लिए करूँगा, जिनका उपयोग मैं इस पोस्ट के बाकी हिस्सों के लिए करूँगा। यह आधार तालिका होगी :
select * from history;
+--------+----------+-----------+
| hostid | itemname | itemvalue |
+--------+----------+-----------+
| 1 | A | 10 |
| 1 | B | 3 |
| 2 | A | 9 |
| 2 | C | 40 |
+--------+----------+-----------+
यह हमारा लक्ष्य होगा, सुंदर धुरी तालिका :
select * from history_itemvalue_pivot;
+--------+------+------+------+
| hostid | A | B | C |
+--------+------+------+------+
| 1 | 10 | 3 | 0 |
| 2 | 9 | 0 | 40 |
+--------+------+------+------+
में मान history.hostid
स्तंभ बन जाएगा y- मानों पिवट तालिका में। history.itemname
कॉलम में मान x-मान (स्पष्ट कारणों के लिए) बन जाएंगे ।
जब मुझे पिवट टेबल बनाने की समस्या को हल करना होगा, तो मैं इसे तीन-चरणीय प्रक्रिया (वैकल्पिक चौथे चरण के साथ) का उपयोग करके निपटाता हूं:
- ब्याज के कॉलम का चयन करें, यानी y-मान और x-मान
- अतिरिक्त स्तंभों के साथ आधार तालिका का विस्तार करें - प्रत्येक एक्स-मूल्य के लिए एक
- समूह और विस्तारित तालिका को एकत्रित करें - प्रत्येक y- मूल्य के लिए एक समूह
- (वैकल्पिक) कुल तालिका को संक्षिप्त करें
आइए इन चरणों को अपनी समस्या पर लागू करें और देखें कि हमें क्या मिलता है:
चरण 1: ब्याज के कॉलम चुनें । वांछित परिणाम में, hostid
प्रदान करता है y- मानों और itemname
प्रदान करता है एक्स-मूल्यों ।
चरण 2: अतिरिक्त स्तंभों के साथ आधार तालिका का विस्तार करें । हमें आमतौर पर प्रति-मूल्य एक कॉलम की आवश्यकता होती है। याद रखें कि हमारा x- मान स्तंभ है itemname
:
create view history_extended as (
select
history.*,
case when itemname = "A" then itemvalue end as A,
case when itemname = "B" then itemvalue end as B,
case when itemname = "C" then itemvalue end as C
from history
);
select * from history_extended;
+--------+----------+-----------+------+------+------+
| hostid | itemname | itemvalue | A | B | C |
+--------+----------+-----------+------+------+------+
| 1 | A | 10 | 10 | NULL | NULL |
| 1 | B | 3 | NULL | 3 | NULL |
| 2 | A | 9 | 9 | NULL | NULL |
| 2 | C | 40 | NULL | NULL | 40 |
+--------+----------+-----------+------+------+------+
ध्यान दें कि हमने पंक्तियों की संख्या नहीं बदली है - हमने सिर्फ अतिरिक्त कॉलम जोड़े हैं। NULL
एस के पैटर्न पर भी ध्यान दें - एक पंक्ति जिसमें itemname = "A"
नए कॉलम के लिए एक गैर-शून्य मान है A
, और अन्य नए कॉलम के लिए शून्य मान हैं।
चरण 3: समूह और विस्तारित तालिका एकत्र करें । हमें इसकी आवश्यकता है group by hostid
, क्योंकि यह y-मान प्रदान करता है:
create view history_itemvalue_pivot as (
select
hostid,
sum(A) as A,
sum(B) as B,
sum(C) as C
from history_extended
group by hostid
);
select * from history_itemvalue_pivot;
+--------+------+------+------+
| hostid | A | B | C |
+--------+------+------+------+
| 1 | 10 | 3 | NULL |
| 2 | 9 | NULL | 40 |
+--------+------+------+------+
(ध्यान दें कि अब हमारे पास एक पंक्ति प्रति y-value है।) ठीक है, हम लगभग वहाँ हैं! हमें बस उन कुरूप NULL
एस से छुटकारा पाने की आवश्यकता है ।
चरण 4: पहले से बताएं । हम सिर्फ शून्य मानों को शून्य से प्रतिस्थापित करने जा रहे हैं, इसलिए परिणाम सेट देखने के लिए अच्छा है:
create view history_itemvalue_pivot_pretty as (
select
hostid,
coalesce(A, 0) as A,
coalesce(B, 0) as B,
coalesce(C, 0) as C
from history_itemvalue_pivot
);
select * from history_itemvalue_pivot_pretty;
+--------+------+------+------+
| hostid | A | B | C |
+--------+------+------+------+
| 1 | 10 | 3 | 0 |
| 2 | 9 | 0 | 40 |
+--------+------+------+------+
और हम कर रहे हैं - हमने MySQL का उपयोग करके एक अच्छी, सुंदर धुरी तालिका बनाई है।
इस प्रक्रिया को लागू करते समय विचार:
- अतिरिक्त कॉलम में किस मूल्य का उपयोग करना है। मैंने
itemvalue
इस उदाहरण में इस्तेमाल किया
- अतिरिक्त कॉलम में उपयोग करने के लिए "तटस्थ" मान क्या है। मैंने उपयोग किया
NULL
, लेकिन यह आपकी सटीक स्थिति के आधार पर भी हो सकता है 0
या हो सकता ""
है
- समूहीकरण के समय कौन से कार्य का उपयोग करना है। मैं प्रयोग किया जाता
sum
है, लेकिन count
और max
भी अक्सर इस्तेमाल किया जाता है ( max
अक्सर जब एक-पंक्ति "वस्तुओं" है कि कई पंक्तियों में फैल गया था के निर्माण में किया जाता है)
- y-मानों के लिए कई स्तंभों का उपयोग करना। यह समाधान केवल y- मानों के लिए एक कॉलम का उपयोग करने तक सीमित नहीं है - बस अतिरिक्त कॉलम को
group by
क्लॉज में प्लग करें (और उन्हें मत भूलना select
)
ज्ञात सीमाएँ:
- यह समाधान पिवट टेबल में एन कॉलम की अनुमति नहीं देता है - बेस टेबल को बढ़ाते समय प्रत्येक पिवट कॉलम को मैन्युअल रूप से जोड़ा जाना चाहिए। तो 5 या 10 x-मानों के लिए, यह समाधान अच्छा है। 100 के लिए, इतना अच्छा नहीं है। संग्रहीत प्रक्रियाओं के साथ कुछ समाधान हैं जो एक क्वेरी उत्पन्न करते हैं, लेकिन वे सही होने के लिए बदसूरत और मुश्किल हैं। मुझे वर्तमान में इस समस्या को हल करने के लिए एक अच्छा तरीका नहीं पता है जब धुरी तालिका में बहुत सारे कॉलम होने चाहिए।