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

后端 未结 2 1974
佛祖请我去吃肉
佛祖请我去吃肉 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:33

    This is non-standard syntax:

    SELECT *
    ...
    GROUP BY RES.RES_ID
    

    Here you have asked for every column (select *) but only specified one column under group by. ONLY MySQL allows this non-standard GROUP BY syntax which is controlled by server settings. Those default settings have recently changed and you may find many our queries using non-standard GROUP BY could fail in future.

    A standards compliant GROUP BY clause specifies ALL "non-aggregating" columns. Meaning you must specify every column not using SUM/COUNT/AVG/MIN/MAX etc.


    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
    

    That query has 2 forms of join syntax. **FROM t1,t2,t3 ** is ancient and unwise and is NOT good practice. Also; never "combine" this old syntax form with the more recent join syntax in a single query as that can lead to query errors.

    Just do NOT use commas between tables in the from clause this simple step will make you use the better syntax all he time.

    By the way FROM TOPICS, CHAPTERS, RESOURCES AS RES with nothing to limit these in a where clause will produce:

    Multiply every row in TOPICS by every row in CHAPTERS by every row in RESOURCES. In other words a "Cartesian product". In more recent syntax your query translates to:

    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
    

提交回复
热议问题