JOIN with GROUP BY in a Normalized DB about Resources, Topics & Chapters

后端 未结 2 1973
佛祖请我去吃肉
佛祖请我去吃肉 2021-01-29 15:25

I\'ve normalized my DB but can\'t seem to return the data I\'m looking for in the right way.

I\'ve got 5 tables:

  1. Resources (5 resources)
  2. Topics (1
2条回答
  •  执笔经年
    2021-01-29 15:32

    I can't really distinguish what you're trying to achieve, but it sounds like you're simply looking to obtain a table that shows every chapter with its topic and resource.

    If so, then the following SQL:

    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;
    

    will return just that, as per http://sqlfiddle.com/#!9/ddf252/12

    Or, ignoring the join IDs in the select:

    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
    

    as per http://sqlfiddle.com/#!9/ddf252/14

    If that's not what you're looking for, could you elaborate a little on what results you're looking to see?

    Edit: To return a more concise list with all associated records

    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
    

    As per http://sqlfiddle.com/#!9/ddf252/30

    Finally, to group these by chapter and topic:

    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
    

    As seen here: http://sqlfiddle.com/#!9/ddf252/85

    I've checked the results over, and they look fine - but double check, as it's gone a bit like MySQL Inception in my head (it's past 1am here)

    Further addition: Distinct values per resource

        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
    

    See http://sqlfiddle.com/#!9/ddf252/88

提交回复
热议问题