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
是不必要的?)
在我正在开发的图书馆管理系统中,我有一个 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
是不必要的?)