【发布时间】:2017-02-28 22:09:51
【问题描述】:
感谢Paul Spiegel's answer 上一个问题,我在数据库dab 中有一个表tab,它由四列组成。一个简单的,一个 ID 列 (id),它也是主键 (int),一个 pat 列 (varchar(255)),一个 path 列 (varchar(191)),最后是 has_tree (位(1))。
id pat path has_tree
1 AA 1 1
2 ABA 1/2 1
3 ABCA 1/3 1
4 ABA 1/5 0
5 AB 2 0
6 BBB 2/1 1
7 CAB 2/2 1
8 ABC 1/4 0
9 ABC 1/5/7 1
10 ABA 3/2 1
给定一个pat 值(如果存在),我想要
- 所有唯一的
pat值(包括输入的has_tree==1), - 他们的路径包含输入的路径,
- 在哪里
has_tree == 1。
所以输入 AA 应该返回 ['AA', 'ABA', 'ABCA', 'ABC']。
重要的说明是输入pat 的path 不一定是单个项目“根路径”,换句话说:输入path 很可能类似于1/12/45/966,其中案例我想要所有唯一的pat 值,其中path 是1/12/45/966 的后代,has_tree 是1。另一个说明是路径可以很深,所以即使输入path是1,结果也可以更深很多层,例如1/22/36/88/98/455/878/1205/2555.
Paul 建议了以下查询,该查询适用于建议的数据结构,但是您可以看到当前的结构和要求略有不同。 (另请注意,我有一个包含多个表的数据库。所以在数据库dab 中给定一个表tab 我想执行脚本。)
SELECT t.*
FROM tree t
CROSS JOIN tree r -- root
WHERE r.CELL = '3B0'
AND t.path LIKE CONCAT(r.path, '%');
我正在尝试使用 PHP 执行此操作,然后调用一些 SQL 数据库。 是否可以以通用、高性能的形式编写它以使其适用于 PostgreSQL、MySQL 和其他?如果没有,我至少希望看到 MySQL 和 PostgreSQL 变体。
在上面 Paul 的示例代码的基础上,我认为应该是这样的,但我不确定。 我也不确定为什么JOIN 运算符是必要的,以及它在这种情况下的作用(我知道它通常做什么,但不知道为什么在这种情况下它是必要的)。我确信这段代码可以改进、修复,并使其更适用于所有 SQL 风格?此外,我没有看到我在下面的尝试在输出中包含当前输入 pat。
SELECT t.pat
FROM `tab` t
JOIN `tab` r
WHERE r.pat = 'AA' -- input
AND t.path LIKE CONCAT(r.path, '/', '%')
AND t.has_tree = 1;
额外问题:我已索引除has_tree 之外的所有列。也为该列编制索引是否有益?
【问题讨论】:
标签: mysql postgresql