मैं इस समस्या को हल करने के लिए उठाए जाने वाले कदमों की कुछ लंबी और अधिक विस्तृत व्याख्या जोड़ने जा रहा हूं। अगर यह बहुत लंबा है तो मैं क्षमा चाहता हूँ।
मैं आपके द्वारा दिए गए आधार के साथ शुरू करूँगा और इसका उपयोग कुछ शब्दों को परिभाषित करने के लिए करूँगा जिनका उपयोग मैं इस पोस्ट के बाकी हिस्सों के लिए करूँगा। यह आधार तालिका होगी :
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-मान
- आधार तालिका को अतिरिक्त स्तंभों के साथ विस्तारित करें -- प्रत्येक के लिए एक x-मान
- विस्तृत तालिका को समूहित और समेकित करें -- प्रत्येक y-मान . के लिए एक समूह
- (वैकल्पिक) समेकित तालिका को सुंदर बनाएं
आइए इन चरणों को अपनी समस्या पर लागू करें और देखें कि हमें क्या मिलता है:
चरण 1:रुचि के कॉलम चुनें . वांछित परिणाम में, hostid
y-मान . प्रदान करता है और itemname
x-मान . प्रदान करता है ।
चरण 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
. के पैटर्न पर भी ध्यान दें s -- 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-मान एक पंक्ति है।) ठीक है, हम लगभग वहाँ हैं! हमें बस उन बदसूरत 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
. करना न भूलें उन्हें)
ज्ञात सीमाएँ:
- यह समाधान पिवट तालिका में n कॉलम की अनुमति नहीं देता है - आधार तालिका का विस्तार करते समय प्रत्येक पिवट कॉलम को मैन्युअल रूप से जोड़ा जाना चाहिए। तो 5 या 10 x-मानों के लिए, यह समाधान अच्छा है। 100 के लिए, इतना अच्छा नहीं। क्वेरी उत्पन्न करने वाली संग्रहीत प्रक्रियाओं के साथ कुछ समाधान हैं, लेकिन वे बदसूरत हैं और सही होने में मुश्किल हैं। मुझे वर्तमान में इस समस्या को हल करने का एक अच्छा तरीका नहीं पता है जब पिवट टेबल में बहुत सारे कॉलम होने चाहिए।