JOIN 查询的奇怪行为

Odd behavior of a JOIN query

在我正在开发的图书馆管理系统中,我有一个 table 和一个文学体裁树。它们像 IP 一样编码(代码 2. 诗歌,代码 2.1. 史诗,代码 2.1.2. 拉丁史诗等)。

IP-like 代码不仅可以计算特定类型,还可以计算所有子类型。如果我想知道图书馆里有多少首诗,我所要做的就是数 2.% 个代码。

由于树将根据图书馆的需要填充,当他们得到新书时,有一个名为 ord_vis 的字段指定行的可视化顺序(即新行关于1911 年的 Italian-Turkish War 必须在第一次世界大战和第二次世界大战之前显示,即使插入在六天之后 War)。

在我决定使用以下查询计算标题数量之前,树一直运行得很顺利:

SELECT  a.id, a.code, a.level, a.parent, a.text,
        GROUP_CONCAT( b.text ORDER BY  b.ord_vis SEPARATOR ', ' ) AS subs,
        COUNT( books.id ) AS total
    FROM  tree AS a
    LEFT JOIN  books ON books.code LIKE CONCAT( a.code, '%' )
    LEFT JOIN  tree AS b ON b.parent = a.id
      AND  b.level = a.level +1
    WHERE  a.parent =42 -- this value is the user query
    GROUP BY  a.id
    ORDER BY  a.ord_vis ASC

奇怪的是,如果 total > 0 或 NOT NULL,则显示的 subs 的数量与 total 的数量相同:有 6 本书和 3 个子类型,我得到 sub 喜欢 "sub1, sub1, sub2, sub2, sub3, sub3".

total为0时,subs以正确的编号和顺序显示。

我使用所有可用的 JOIN 选项测试查询均未成功,我还尝试更改 JOIN 和 SELECT 字段的顺序。

我解决了以这种方式修改获取潜艇的行的问题:GROUP_CONCAT(DISTINCT b.text ORDER BY b.ord_vis SEPARATOR ', ' ) AS subs 但我想了解为什么我在没有 DISTINCT.

的情况下得到那些奇怪的结果

有什么线索吗?

JOIN 往往会使行数激增。 DISTINCT是一种统治爆炸的方式。

另一种方法(有时有效)对我们来说是相关子查询。这可能(或可能不会)运行 更慢:

SELECT  a.id, a.code, a.level, a.parent, a.text, 
        ( SELECT  GROUP_CONCAT( text ORDER BY  ord_vis SEPARATOR ', ' )
            FROM  tree
            WHERE  parent = a.id
              AND  level = a.level +1 ) AS subs,
        COUNT( books.id ) AS total
    FROM  tree AS a
    LEFT JOIN  books ON books.code LIKE CONCAT( a.code, '%' )
    WHERE  a.parent =42 -- this value is the user query
    GROUP BY  a.id
    ORDER BY  a.ord_vis ASC 

(我怀疑 LEFT 是不必要的?)