获取包含特定单元格中的输入值的行,按其他单元格筛选,返回其他单元格值

时间:2017-02-28 22:09:52

标签: mysql postgresql mysqli

感谢上一个问题的Paul Spiegel's answer,我在数据库tab中有一个表dab,它由四列组成。一个简单的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值(包括输入' s,如果has_tree==1),
  • 其路径包含输入路径
  • 以及has_tree == 1

因此输入AA应返回['AA', 'ABA', 'ABCA', 'ABC']

重要的评论是,输入path的{​​{1}}不一定是单个项目的根路径,换句话说:它很可能是输入pat类似于path,在这种情况下,我希望1/12/45/966pat的后代且其中{{1}的所有唯一path值是1/12/45/966。另一个注意事项是路径可能非常深,因此即使输入has_tree1,结果也可能更深层次,例如path

Paul建议使用以下查询,该查询适用于建议的数据结构,但是您可以看到当前的结构和要求略有不同。 (另请注意,我有一个包含多个表的数据库。因此,在数据库1中给出一个表1/22/36/88/98/455/878/1205/2555我想执行该脚本。)

tab

我试图用PHP做这个,然后调用一些SQL数据库。 是否有可能以通用,高性能的形式编写它,以便它适用于PostgreSQL,MySQL(i)和其他?如果没有,我至少想看看MySQLi和PostgreSQL变体。

基于保罗上面的示例代码,我认为这将是这些内容,但我不确定。 我也不确定为什么dab运算符是必要的以及它在此上下文中的作用(我知道它通常做什么,但不知道为什么在这种情况下有必要)。我确信这些代码可以改进,修复,并使所有SQL风格更通用?另外,我没有看到下面的尝试包括输出中的当前输入SELECT t.* FROM tree t CROSS JOIN tree r -- root WHERE r.CELL = '3B0' AND t.path LIKE CONCAT(r.path, '%');

JOIN

加分问题:我已将所有列编入索引,但pat除外。将该列编入索引也是有益的吗?

1 个答案:

答案 0 :(得分:1)

首先注意:路径应以反斜杠结尾('1/''1/2/'而不是'1''1/2')。这很重要,否则您无法匹配子树的根。例如:

WHERE path LIKE '1/%'

'1'不匹配,但会与'1/'匹配。

您也可以不跳过查询中的反斜杠:

WHERE path LIKE '1%'

将匹配根'1',但也会匹配'10..'

现在回答您的问题:如果您已经知道根节点的路径,那么您就不需要加入:

SELECT * FROM tab WHERE path LIKE '1/%' AND has_tree

只获得" unique"拍你可以使用DISTINCT关键字:

SELECT DISTINCT pat
FROM tab
WHERE path LIKE '1/%'
  AND has_tree

那就是它。

如果您不知道根路径但只知道pat值,则需要运行两个查询(首先获取路径然后获取后代)或使用连接。

的PostgreSQL:

SELECT DISTINCT t.pat
FROM tab t
JOIN tab r ON t.path LIKE r.path || '%'
WHERE r.pat = 'AA' -- input
  AND t.has_tree

演示:http://rextester.com/EXZT43019

MySQL的:

SELECT DISTINCT t.pat
FROM tab t
JOIN tab r ON t.path LIKE CONCAT(r.path, '%')
WHERE r.pat = 'AA' -- input
  AND t.has_tree

演示:http://rextester.com/DNHRJ83456

注意:正如您将在domo中看到的,如果您使用以下命令更改模式,您还可以在MySQL中使用管道(||)进行连接:

SET sql_mode=PIPES_AS_CONCAT;

关于索引:布尔列的索引通常不是很有用。但是,您只能确定是否测试它。对于给定的查询,(has_tree, path)上的复合索引可能会提高性能。