mysql - संसाधन, विषय और अध्यायों के बारे में सामान्यीकृत डीबी में ग्रुप द्वारा जुड़ें




join group-by normalization (3)

मैंने अपने डीबी को सामान्य किया है, लेकिन मुझे सही तरीके से देख रहे डेटा वापस नहीं लौटा सकता।

मेरे पास 5 टेबल हैं:

  1. संसाधन (5 संसाधन)
  2. विषय (10 विषयों)
  3. अध्याय (10 अध्याय)
  4. विषय-से-संसाधन (संसाधन लिंक के लिए 18 विषय)
  5. विषय-से-अध्याय (अध्याय लिंक्स के लिए 18 विषय)

इस एसक्यूएल बेड़े की जाँच करें ...

मुझे संसाधन तालिका में सभी रिकॉर्ड एकत्र करने और उनके संबंधित विषयों और अध्याय (विषय-से-संसाधन और विषय-से-अध्याय तालिकाओं से) प्रत्येक समूह को इकट्ठा करने की आवश्यकता है

क्या कोई भी एसक्यूएल क्वेरी का सुझाव दे सकता है कि वह अपने संसाधन विषय और अध्यायों के साथ 5 संसाधन रिकॉर्ड्स लौटाए?

मैंने ग्रुप के साथ मिलकर काम करने की कोशिश की है और यह रिकॉर्डसेट को 5 संसाधनों को सम्मिलित करता है, लेकिन मुझे अन्य सभी जानकारी (विषय और अध्याय) की आवश्यकता नहीं है

SELECT * FROM TOPICS, CHAPTERS, RESOURCES AS RES
INNER JOIN TOPICS_to_RESOURCE AS TR ON RES.RES_ID = TR.TR_RESID
INNER JOIN TOPICS_to_CHAPTER AS TCH ON TR.TR_TID = TCH.TCH_TID
GROUP BY RES.RES_ID

Answers

यह गैर मानक वाक्यविन्यास है:

SELECT *
...
GROUP BY RES.RES_ID

यहां आपने प्रत्येक कॉलम (* चुनें) के लिए कहा है, लेकिन केवल समूह के अंतर्गत निर्दिष्ट एक कॉलम। केवल MySQL इस गैर मानक ग्रुप द्वारा वाक्यविन्यास की अनुमति देता है जो कि सर्वर सेटिंग्स द्वारा नियंत्रित है। उन डिफ़ॉल्ट सेटिंग्स हाल ही में बदल दी गई हैं और आप कई गैर-मानक ग्रुप BY का उपयोग कर भविष्य में विफल हो सकते हैं।

एक मानदंड अनुपालन ग्रुप बाय क्लॉज सभी "गैर-एकत्रित" कॉलम निर्दिष्ट करता है अर्थ है कि आपको प्रत्येक कॉलम को SUM / COUNT / AVG / MIN / MAX आदि का उपयोग नहीं करना चाहिए।

SELECT * FROM TOPICS, CHAPTERS, RESOURCES AS RES
INNER JOIN TOPICS_to_RESOURCE AS TR ON RES.RES_ID = TR.TR_RESID
INNER JOIN TOPICS_to_CHAPTER AS TCH ON TR.TR_TID = TCH.TCH_TID
GROUP BY RES.RES_ID

उस क्वेरी में वाक्य रचना में शामिल होने के दो रूप हैं। ** टी 1, टी 2, टी 3 ** से प्राचीन और मूर्ख है और यह अच्छा अभ्यास नहीं है। इसके अलावा, कभी भी एक एकल क्वेरी में अधिक हाल ही में शामिल वाक्यविन्यास के साथ इस पुराने सिंटैक्स फॉर्म को "गठबंधन" न करें क्योंकि क्वेरी त्रुटियों को जन्म दे सकता है

बस खंड से तालिकाओं के बीच अल्पविराम का प्रयोग न करें, यह सरल कदम आपको सभी समय के बेहतर सिंटैक्स का उपयोग कर देगा।

जिस तरह से विषयों से, अध्याय, संसाधनों के रूप में संसाधनों के साथ कुछ नहीं करने के लिए इन सीमाओं का निर्माण होगा जहां खंड:

RESOURCES में हर पंक्ति के अनुसार CHAPTERS में प्रत्येक पंक्ति में टॉप में हर पंक्ति गुणा करें। दूसरे शब्दों में "कार्टेशियन उत्पाद" अधिक हाल की वाक्यविन्यास में आपकी क्वेरी निम्न का अनुवाद करती है:

SELECT * FROM TOPICS
CROSS JOIN CHAPTERS
CROSS JOIN RESOURCES AS RES
INNER JOIN TOPICS_to_RESOURCE AS TR ON RES.RES_ID = TR.TR_RESID
INNER JOIN TOPICS_to_CHAPTER AS TCH ON TR.TR_TID = TCH.TCH_TID
GROUP BY RES.RES_ID

मैं वास्तव में क्या हासिल करने की कोशिश कर रहा हूं, लेकिन यह वास्तव में अलग नहीं कर सकता, लेकिन ऐसा लगता है कि आप केवल एक तालिका प्राप्त करने की तलाश कर रहे हैं जो प्रत्येक अध्याय को उसके विषय और संसाधन के साथ दिखाता है।

यदि हां, तो निम्न एसक्यूएल:

select * from resources r
JOIN topics_to_resource ttr ON ttr.tr_resid = r.res_id
JOIN topics t on t.t_id = ttr.tr_tid
JOIN topics_to_chapter ttc on ttc.tch_tid = t.t_id
JOIN chapters ch ON ch.ch_id = tch_chid
ORDER BY r.res_id;

सिर्फ यही होगा, http://sqlfiddle.com/#!9/ddf252/12 के अनुसार

या, चुनने में शामिल होने के आईडी की अनदेखी करें:

select r.res_id, r.res_name, t.t_id, t.t_name, ch.ch_id, ch.ch_name from resources r
JOIN topics_to_resource ttr ON ttr.tr_resid = r.res_id
JOIN topics t on t.t_id = ttr.tr_tid
JOIN topics_to_chapter ttc on ttc.tch_tid = t.t_id
JOIN chapters ch ON ch.ch_id = tch_chid
ORDER BY r.res_id, t.t_id, ch.ch_id

http://sqlfiddle.com/#!9/ddf252/14 के अनुसार

यदि वह ऐसा नहीं है जो आप ढूंढ रहे हैं, तो क्या आप उन परिणामों के बारे में थोड़ा विस्तारित कर सकते हैं जो आप देख रहे हैं?

संपादित करें : सभी संबद्ध रिकॉर्ड के साथ एक अधिक संक्षिप्त सूची वापस करने के लिए

select 
CONCAT(r.res_id,': ',r.res_name) 'Resources', 
GROUP_CONCAT(CONCAT(' (',t.t_id,': ',t.t_name,')')) 'Topics', 
GROUP_CONCAT(CONCAT(' (',ch.ch_id,': ',ch.ch_name,')')) 'Chapters'
from resources r
JOIN topics_to_resource ttr ON ttr.tr_resid = r.res_id
JOIN topics t on t.t_id = ttr.tr_tid
JOIN topics_to_chapter ttc on ttc.tch_tid = t.t_id
JOIN chapters ch ON ch.ch_id = tch_chid
GROUP BY r.res_id
ORDER BY r.res_id, t.t_id, ch.ch_id

Http://sqlfiddle.com/#!9/ddf252/30 के अनुसार

अंत में , ये अध्याय और विषय के अनुसार समूह:

select 
CONCAT(res_id,': ',res_name) 'Resources', 
GROUP_CONCAT(`chapters` order by chapters separator '\n') as 'Content'
FROM
  (SELECT r.res_id 'res_id',
          r.res_name 'res_name', 
          t.t_id 't_id',
          t.t_name 't_name',
          CONCAT(t.t_name,': (',GROUP_CONCAT(ch.ch_name ORDER BY t.t_name separator ','),')') 'Chapters'
    FROM resources r
      JOIN topics_to_resource ttr ON ttr.tr_resid = r.res_id
      JOIN topics t on t.t_id = ttr.tr_tid
      JOIN topics_to_chapter ttc on ttc.tch_tid = t.t_id
      JOIN chapters ch ON ch.ch_id = tch_chid
    GROUP BY res_id, t_id
    ORDER BY r.res_id, t.t_id, ch.ch_id) as t
GROUP BY res_id

जैसा कि यहां देखा गया है: http://sqlfiddle.com/#!9/ddf252/85

मैंने परिणामों की जांच की है, और वे ठीक दिखते हैं - परन्तु दोबारा जांचें, क्योंकि यह मेरे सिर में MySQL की शुरुआत की तरह थोड़ी चली गई है (यह पिछले 1 बजे है)

इसके अलावा इसके अलावा: प्रति संसाधनों से अलग मूल्य

    select CONCAT(r.res_id,': ',r.res_name) 'Resources', GROUP_CONCAT(distinct t_name separator ',') 'Topics', 
GROUP_CONCAT(distinct ch.ch_name separator ',') 'Chapters'
from resources r
JOIN topics_to_resource ttr ON ttr.tr_resid = r.res_id
JOIN topics t on t.t_id = ttr.tr_tid
JOIN topics_to_chapter ttc on ttc.tch_tid = t.t_id
JOIN chapters ch ON ch.ch_id = tch_chid
GROUP BY r.res_id
ORDER BY r.res_id, t.t_id, ch.ch_id

देखें http://sqlfiddle.com/#!9/ddf252/88


यदि आप प्रत्येक पंक्ति के लिए GREATEST () का चयन कर रहे हैं

SELECT GREATEST(field1, field2)

यदि फ़ील्ड में से कोई एक न्यूल है तो यह शून्य वापस आ जाएगा। आप इसे हल करने के लिए IFNULL का उपयोग कर सकते हैं

SELECT GREATEST(IFNULL(field1, 0), IFNULL(field2, 0))




mysql sql join group-by normalization