Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/search/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Mysql (快速)在不考虑行继承的情况下进行搜索_Mysql_Search - Fatal编程技术网

Mysql (快速)在不考虑行继承的情况下进行搜索

Mysql (快速)在不考虑行继承的情况下进行搜索,mysql,search,Mysql,Search,我目前有一个表,其中包含以下列: id (INT) parent_id (INT) col0 col1 col2 例如,此表中保存了以下条目: 1 NULL abc def NULL 2 1 test NULL NULL 3 1 NULL NULL xyz 现在我想搜索所有A行,其中没有任何B行指向它们。此外,行值应该是当前行中存在的值,或者如果存在空值,则应该考虑父级的值 为了说明我的要求,我想举几个例

我目前有一个表,其中包含以下列:

id (INT)
parent_id (INT)
col0
col1
col2
例如,此表中保存了以下条目:

1     NULL   abc     def     NULL
2     1      test    NULL    NULL
3     1      NULL    NULL    xyz
现在我想搜索所有A行,其中没有任何B行指向它们。此外,行值应该是当前行中存在的值,或者如果存在空值,则应该考虑父级的值

为了说明我的要求,我想举几个例子:

SEARCH(col0=test) => #2 (#1 has some children, #3.col0 = abc (inherited from #1))
SEARCH(col1=def) => #2, #3 (#1 has some children)
SEARCH(col2=xyz) => #3 (#1 has some children, #2.col2 = NULL (inherited from #1))
有人知道如何在MySQL中实现这样的搜索吗

SELECT
# if first table has no value, use parent table
IF(t1.col0, t1.col0, t2.col0) as virtcol0,
IF(t1.col1, t1.col1, t2.col1) as virtcol1,
IF(t1.col2, t1.col2, t2.col2) as virtcol2
FROM table as t1
LEFT JOIN table as t2 ON t1.parent_id = t2.id
LEFT JOIN table as t3 ON t1.id = t3.parent_id
# t3 would be children of t1. We don't want t1 to procreate. :)
WHERE t3.id IS NULL
# Your actual search goes here:
AND virtcol0/1/2 = whatever
快?不可以。您可以从中获得的最佳索引使用是id/parent\u id上的连接

如果有大量数据和较小的结果集,则可以直接在索引上查询列,然后在单独的查询中运行父项和子项检查。这比在一个巨大的表上运行上面的查询要快得多

快?不可以。您可以从中获得的最佳索引使用是id/parent\u id上的连接


如果有大量数据和较小的结果集,则可以直接在索引上查询列,然后在单独的查询中运行父项和子项检查。这比在大型表上运行上述查询要快得多。

最干净的解决方案可能是创建一个合并了父列和子列的视图:

CREATE VIEW foo
AS SELECT
  c.id AS id,
  COALESCE(c.col0, p.col0) AS col0,
  COALESCE(c.col1, p.col1) AS col1,
  COALESCE(c.col2, p.col2) AS col2
FROM table AS c
  LEFT JOIN table AS p ON p.id = c.parent_id
WHERE NOT EXISTS
  (SELECT * FROM table AS x WHERE c.id = x.parent_id)
然后,您可以对该视图编写查询,就像它是一个普通表一样

然而,正如Mantriur所指出的,这并不是很有效。如果表不经常更改,您可以使用而不是创建视图来创建包含合并数据的实际表,并在其上创建一些索引,以便高效地查询。但是,这样的表不会像视图那样跟踪对原始表的更改

原则上,您可以使用触发器或应用程序逻辑在基础表更改时实时更新合并表,但这很容易变得复杂并容易出错。不幸的是,虽然其他一些RDBMS确实支持,这基本上是一种自动实现的方法,但MySQL目前不支持


嗯,反正不是天生的。有,尽管我自己没有尝试过。

最干净的解决方案可能是创建一个父列和子列合并的视图:

CREATE VIEW foo
AS SELECT
  c.id AS id,
  COALESCE(c.col0, p.col0) AS col0,
  COALESCE(c.col1, p.col1) AS col1,
  COALESCE(c.col2, p.col2) AS col2
FROM table AS c
  LEFT JOIN table AS p ON p.id = c.parent_id
WHERE NOT EXISTS
  (SELECT * FROM table AS x WHERE c.id = x.parent_id)
然后,您可以对该视图编写查询,就像它是一个普通表一样

然而,正如Mantriur所指出的,这并不是很有效。如果表不经常更改,您可以使用而不是创建视图来创建包含合并数据的实际表,并在其上创建一些索引,以便高效地查询。但是,这样的表不会像视图那样跟踪对原始表的更改

原则上,您可以使用触发器或应用程序逻辑在基础表更改时实时更新合并表,但这很容易变得复杂并容易出错。不幸的是,虽然其他一些RDBMS确实支持,这基本上是一种自动实现的方法,但MySQL目前不支持


嗯,反正不是天生的。有,尽管我自己没有尝试过。

给出一些示例行和所需的结果集。给出一些示例行和所需的结果集。如果您的结果可以包含数字零或空字符串,您可能希望将IFs调整为不为NULL…甚至。以前从未听说过这个。非常有用!:如果我没弄错的话,这会一直持续到深度大于3?是否有可能支持无限深度?应该可以使用循环:。但这确实超出了我在SQL查询中所做的范围:如果您的结果可以包含数字零或空字符串,您可能希望将IFs调整为NOT NULL…甚至。以前从未听说过。非常有用!:如果我没弄错的话,这会一直持续到深度大于3?是否有可能支持无限深度?应该可以使用循环:。但这确实超出了我在SQL查询中所做的范围: