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

هنا كنت قد طلبت لكل عمود (حدد *) ولكن المحدد فقط عمود واحد تحت مجموعة من قبل. فقط الخلية تسمح هذه البنية غير القياسية غروب بي التي يتم التحكم فيها بواسطة إعدادات الخادم. وقد تغيرت هذه الإعدادات الافتراضية مؤخرا وقد تجد العديد من طلبات البحث التي نستخدمها غير القياسية غروب بي قد تفشل في المستقبل.

ويحدد شرط غروب بي المتوافق مع المعايير جميع الأعمدة "غير المجمعة". وهذا يعني أنه يجب تحديد كل عمود لا يستخدم سوم / كونت / أفغ / مين / ماكس وما إلى ذلك.

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

يحتوي هذا الاستعلام على شكلين من بناء الجملة. ** من T1، T2، t3 ** هو القديم وغير الحكيم وليس ممارسة جيدة. أيضا؛ أبدا "الجمع" هذا النموذج بناء الجملة القديم مع بناء جملة الانضمام الأخيرة في استعلام واحد كما يمكن أن يؤدي إلى أخطاء الاستعلام.

فقط لا تستخدم الفواصل بين الجداول في من شرط هذه الخطوة البسيطة سوف تجعلك استخدام بناء أفضل في كل وقت.

بالمناسبة من المواضيع، والفصول، والموارد كما ريس مع أي شيء للحد من هذه في حيث حيث البند تنتج:

ضرب كل صف في توبيكس من قبل كل صف في تشابترز من قبل كل صف في ريسورسز. وبعبارة أخرى "المنتج الديكارتي". في بناء الجملة الأحدث، يترجم طلب البحث إلى:

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

لقد فحصت النتائج أكثر، وأنها تبدو جيدة - ولكن التحقق المزدوج، كما ذهب قليلا مثل ميسكل بداية في رأسي (انها 1:00 الماضي هنا)

إضافة إضافية: قيم مميزة لكل مورد

    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


إذا كان لصف واحد قيمة في حقل field1 ، وكانت الصفوف الأخرى ذات قيمة فارغة ، فقد يعمل هذا الاستعلام.

SELECT
  FK,
  MAX(Field1) as Field1,
  MAX(Field2) as Field2
FROM 
(
select FK,ISNULL(Field1,'') as Field1,ISNULL(Field2,'') as Field2 from table1
)
tbl
GROUP BY FK






mysql sql join group-by normalization