Mysql
 sql >> डेटाबेस >  >> RDS >> Mysql

mysql पिवट टेबल के साथ परेशानी

जब आप गतिशील या अज्ञात मान को पिवट करने का प्रयास कर रहे हों, तो मैं हमेशा सुझाव दूंगा कि आप पहले क्वेरी के स्थिर या हार्ड-कोडेड संस्करण से शुरू करें, फिर इसे गतिशील SQL में परिवर्तित करें।

MySQL में PIVOT फ़ंक्शन नहीं है, इसलिए परिणाम प्राप्त करने के लिए आपको CASE अभिव्यक्ति के साथ एक समग्र फ़ंक्शन का उपयोग करने की आवश्यकता होगी। कोड का स्थिर संस्करण निम्न के जैसा होगा:

select t.id teamid, 
  t.name teamname, 
  p.id processid, 
  p.name processname,
  max(case when pd.keyname = 'shape' then tpd.value end) shape,
  max(case when pd.keyname = 'vegetable' then tpd.value end) vegetable,
  max(case when pd.keyname = 'fruit' then tpd.value end) fruit,
  max(case when pd.keyname = 'animal' then tpd.value end) animal
from teams t
inner join teamprocesses tp
  on t.id = tp.teamid
inner join TeamProcessDetails tpd
  on tp.id = tpd.teamProcessId
inner join processes p
  on tp.processid = p.id
inner join processdetails pd
  on p.id = pd.processid
  and tpd.processDetailsid = pd.id
group by t.id, t.name, p.id, p.name;

देखें SQL Fiddle with Demo

अब अगर आपके पास keynames . का कोई अनजान नंबर होने वाला है कि आप कॉलम में कनवर्ट करना चाहते हैं, तो आपको तैयार बयान गतिशील एसक्यूएल उत्पन्न करने के लिए। कोड इसके समान होगा:

SET @sql = NULL;
SELECT
  GROUP_CONCAT(DISTINCT
    CONCAT(
      'max(case when pd.keyname = ''',
      keyname,
      ''' then tpd.value end) AS ',
      replace(keyname, ' ', '')
    )
  ) INTO @sql
from ProcessDetails;

SET @sql 
    = CONCAT('SELECT t.id teamid, 
                t.name teamname, 
                p.id processid, 
                p.name processname, ', @sql, ' 
              from teams t
              inner join teamprocesses tp
                on t.id = tp.teamid
              inner join TeamProcessDetails tpd
                on tp.id = tpd.teamProcessId
              inner join processes p
                on tp.processid = p.id
              inner join processdetails pd
                on p.id = pd.processid
                and tpd.processDetailsid = pd.id
              group by t.id, t.name, p.id, p.name;');

PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;

देखें SQL Fiddle with Demo

ध्यान रखने वाली एक बात GROUP_CONCAT कॉलम की स्ट्रिंग बनाने के लिए फ़ंक्शन की डिफ़ॉल्ट अधिकतम लंबाई 1024 है, इसलिए यदि आपके पास इस स्ट्रिंग में बहुत सारे वर्ण होने जा रहे हैं तो आपको group_concat_max_len के सत्र मान को बदलना पड़ सकता है। ।

यह क्वेरी एक परिणाम देगी:

| TEAMID | TEAMNAME | PROCESSID | PROCESSNAME |  SHAPE | VEGETABLE |  FRUIT | ANIMAL |
|      1 |    teamA |         1 |    processA | circle |    carrot |  apple | (null) |
|      1 |    teamA |         2 |    processB | (null) |    (null) | (null) |    dog |



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. कॉलम उपनाम के साथ स्प्रिंग बैच सॉर्ट कुंजी के रूप में - विकृत जहां कथन

  2. com.mchange.v2.resourcepool.CannotAcquireResourceException:एक रिसोर्सपूल अपने प्राथमिक कारखाने या स्रोत से संसाधन प्राप्त नहीं कर सका

  3. तालिका से * चुनें जहां तारीख =आज

  4. ज़ेंड फ्रेमवर्क के तहत MySQL को कैसे कॉन्फ़िगर करें?

  5. सभी MySQL संग्रहीत प्रक्रिया कॉल खोजें?