MySQL:仅当找到 children 时才添加 parent 行(使用 LIKE,相同 table)

MySQL: Adding parent row only if children are found (with LIKE, same table)

我有 table 这样的:

id   |    type      |    parent   |   alias
----------------------------------------------
1    |    Type1     |    0        |   animals,fauna
2    |    Subtype11 |    1        |   cat
3    |    Subtype12 |    1        |   goat
4    |    Subtype13 |    1        |   bird,owl
5    |    Type2     |    0        |
6    |    Type3     |    0        |
7    |    Subtype31 |    6        |   type2 for example,other aliasname
8    |    Subtype32 |    6        |
此 table 用于 live-search 提示系统,它是简单的 parent-child 关系 - 没有更多级别。

我正在使用简单查询:

SELECT id,type FROM table_name WHERE type LIKE '%something%' OR alias LIKE '%something%'

它按我的预期工作,但我需要扩展它。我不仅需要接收单个 children 行,还需要接收它们的 parent 行。

例如。 如果我正在寻找:

(...) WHERE type LIKE '%cat%' OR alias LIKE '%cat%' OR type LIKE '%goat%' OR alias LIKE '%goat%'

我要收的不是单身:

id   |    type      |    parent   |   alias
----------------------------------------------
2    |    Subtype11 |    1        |   cat
3    |    Subtype12 |    1        |   goat

还有他们的 parent(如果有的话!):

id   |    type      |    parent   |   alias
----------------------------------------------
1    |    Type1     |    0        |   animals,fauna
2    |    Subtype11 |    1        |   cat
3    |    Subtype12 |    1        |   goat

与上面完全一样,因为稍后我会检查 parent=0 是否将该行标记为 children 组。

还有一个技巧 - 我也可以按 parent 搜索,例如:

(...) WHERE type LIKE '%Type2%' OR alias LIKE '%Type2%'

应该return:

id   |    type      |    parent   |   alias
----------------------------------------------
5    |    Type2     |    0        |
6    |    Type3     |    0        |
7    |    Subtype31 |    6        |   type2 for example,other aliasname

当然会有大约 500 行不同的 types/aliases - 我需要 return 他们总是 parents.

虽然这很容易做到,但事实并非如此(或者只是我有一些 "brain-damage" :D )

您可以这样做,对 table 从子记录到父记录执行自联接。为这两条记录添加您的条件 (parent/child)。然后根据需要为您希望显示的字段设置别名。

SELECT ch.id, ch.type, prnt.id AS parent_id, prnt.type AS parent_type
FROM   table_name AS ch
       JOIN table_name as prnt
       ON ch.parent = prnt.id
WHERE  (ch.type LIKE '%something%' OR ch.alias LIKE '%something%')
       AND  -- Or "OR" depending on what you are trying to do
       (prnt.type LIKE '%Type2%' OR prnt.alias LIKE '%Type2%');

您可以使用别名左连接 table 并根据父筛选器或子筛选器传递您的 where 子句。

请参阅以下不带 where 子句的查询:

select c.id, c.type,c.alias,p.id,p.type,p.alias from stack c left join stack p on(c.parent=p.id)

+------+-----------+-----------------+------+--------+---------+
| id   | type      | alias           | id   | type   | alias   |
+------+-----------+-----------------+------+--------+---------+
|    2 | Subtype11 | cat             |    1 | Type1  | animals |
|    3 | Subtype12 | goat            |    1 | Type1  | animals |
|    4 | Subtype13 | bird            |    1 | Type1  | animals |
|    5 | Type2     |                 | NULL | NULL   | NULL    |
|    6 | Type3     |                 | NULL | NULL   | NULL    |
|    7 | Subtype31 | type2forexample |    6 | Type3  |         |
|    8 | Subtype32 | Type 32 example |    6 | Type3  |         |
|    1 | Type1     | animals         | NULL | NULL   | NULL    |
+------+-----------+-----------------+------+--------+---------+

请参阅以下在子过滤器上使用 where 子句的查询:

select c.id, c.type,c.alias,p.id,p.type,p.alias from stack c left join stack p on(c.parent=p.id) where c.alias like '%cat%'

+------+-----------+-------+------+-------+---------+
| id   | type      | alias | id   | type  | alias   |
+------+-----------+-------+------+-------+---------+
|    2 | Subtype11 | cat   |    1 | Type1 | animals |
+------+-----------+-------+------+-------+---------+

如果你查询下面没有输出。缺少子元素的地方。因此,将不会获取父项。

select c.id, c.type,c.alias,p.id,p.type,p.alias from stack c left join stack p on(c.parent=p.id) where c.alias like '%cow%';

@gubs 的回答并不完全符合我的假设,但给我提供了另一个解决这个问题的机会。我可以按照建议,在每一行设置父 ID 或 NULL(如果它是父),而不是与父行一起获取一行。

现在我的查询

SELECT p.id AS parent_id,p.type AS parent_type,c.id, c.type 
FROM table_name c 
  LEFT JOIN table_name p 
  ON (c.parent=p.id) 
WHERE 
  c.type LIKE '%cat%' 
OR 
  c.alias LIKE '%cat%'

returns我的专栏

   parent_id   |    parent_type      |    id   |   type
----------------------------------------------------------

所以我可以检查 parent_id 是否为 NULL 并从 'type' 列而不是 'parent_type' 列获取组名。

这个答案让我很满意(它与我的真实数据库完美配合),所以我会接受它:)

感谢您的帮助。