mysql - 获取包含特定单元格中输入值的行,按其他单元格过滤,返回其他单元格值

标签 mysql postgresql

感谢Paul Spiegel's answer关于上一个问题,我有一张 table tab在数据库中dab它由四列组成。一个简单的,一个 ID 列 ( id ),也是主键 (int),一个 pat列 (varchar(255)),a 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'] .

重要说明是 path输入pat不一定是单个项目“根路径”,换句话说:输入 path 很可能是类似于 1/12/45/966在这种情况下,我想要所有独特的 pat值其中 path1/12/45/966 的后代哪里 has_tree1 。另外需要注意的是,路径可以很深,所以即使输入path1 ,结果可以更深层次,例如1/22/36/88/98/455/878/1205/2555 .

Paul 建议使用以下查询,该查询适用于建议的数据结构,但是正如您所看到的,当前的结构和要求略有不同。 (另请注意,我有一个包含多个表的数据库。因此,给定数据库 tab 中的一个表 dab 我想执行该脚本。)

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 变体。

基于保罗上面的示例代码,我认为这会是这样的,但我不确定。 我也不确定为什么 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 之外的所有列建立索引。对该列建立索引也会有好处吗?

最佳答案

第一个注意事项:路径应以反斜杠结尾('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

要仅获得“独特”的拍拍,您可以使用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;

关于索引: bool 列上的索引通常不是很有用。然而,只有测试后才能确定。对于给定的查询,(has_tree, path) 上的复合索引可能会提高性能。

关于mysql - 获取包含特定单元格中输入值的行,按其他单元格过滤,返回其他单元格值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42519660/

相关文章:

mysql - 同时获取每列中每个值的计数

java - org.hibernate.hql.internal.ast.HqlSqlWalker.setAlias(HqlSqlWalker.java:1093)上的NullPointerException

regex - sed 替换匹配复杂正则表达式模式的文本

sql - 具有绑定(bind)参数的用户定义函数

c# - 杀死单一服务

php - 在 PHP 中使用 ' echo ' 时,jquery 仅适用于顶级 SQL 搜索结果

sql - 如何获取组中最新的行

ruby-on-rails - 检测 PostgreSQL json 字段的变化

php - SQL查询的 Eloquent 表示

c# - 哈希密码算法问题