嵌套集SQL查询可检索每个节点的第一个祖先

问题描述

我有一个嵌套集树,我正在搜索一个SQL查询以检索每个节点的第一个祖先。

我将始终获得根节点或所有祖先的列表。 参见:Nested Set Query to retrieve all ancestors of each node

示例:

树:

ROOT
 - A
   - B 
   - C
     - D
 - E
   - F
     - G
     - H
       - I
 - J
   - K

所需的输出:

|    NODE |  ACESTOR |
|---------|----------|
|       A |        A |
|       B |        A |
|       C |        A |
|       D |        A |
|       E |        E |
|       F |        E |
|       G |        E |
|       H |        E |
|       I |        E |
|       J |        J |
|       K |        J |

更新:一些示例数据:

CREATE TABLE `nstree` (
  `sid` int,`left` int,`right` int,`level` int,`name` varchar(255)
);


INSERT INTO `nstree` (`sid`,`left`,`right`,`level`,`name`) VALUES
(1,1,24,'Root'),(2,2,9,'A'),(3,3,4,'B'),(4,5,8,'C'),(5,6,7,'D'),(6,10,19,'E'),(7,11,18,'F'),(8,12,13,'G'),(9,14,17,'H'),(10,15,16,'I'),(11,20,23,'J'),(12,21,22,'K');

将创建此表:

|  sid| left|right|level| name|
|-----|-----|-----|-----|-----|
|    1|    1|   24|    0| Root|
|    2|    2|    9|    1|    A|
|    3|    3|    4|    2|    B|
|    4|    5|    8|    2|    C|
|    5|    6|    7|    3|    D|
|    6|   10|   19|    1|    E|
|    7|   11|   18|    2|    F|
|    8|   12|   13|    3|    G|
|    9|   14|   17|    3|    H|
|   10|   15|   16|    4|    I|
|   11|   20|   23|    1|    J|
|   12|   21|   22|    2|    K|

所有祖先的SQL查询:

SELECT n.sid,n.name,GROUP_CONCAT(p.sid ORDER BY p.left) ancestors 
FROM nstree n
LEFT JOIN nstree p ON p.left < n.left AND p.right > n.right
GROUP BY n.sid; 

将产生以下结果:

|  sid| name|ancestors  
|-----|-----|--------|
|    1| Root|    NULL|
|    2|    A|       1|
|    3|    B|     1,2|
|    4|    C|     1,2|
|    5|    D|   1,4|
|    6|    E|       1|
|    7|    F|     1,6|
|    8|    G|   1,7|
|    9|    H|   1,7|
|   10|    I| 1,9|
|   11|    J|       1|
|   12|    K|    1,11|

但是我只需要root之后的第一个节点

|  sid| name|ancestor| 
|-----|-----|--------|
|    1| Root|    NULL|
|    2|    A|       2|
|    3|    B|       2|
|    4|    C|       2|
|    5|    D|       2|
|    6|    E|       6|
|    7|    F|       6|
|    8|    G|       6|
|    9|    H|       6|
|   10|    I|       6|
|   11|    J|      11|
|   12|    K|      11|

解决方法

据我所知,您只想显示1级祖先。从现有查询开始,您可以只使用条件聚合:

import requests
from bs4 import BeautifulSoup
import xlwt
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
import time
from urllib.parse import urlparse

name = "Joe Sample"
search_query = 'string of info ' + name + ' more info'


driver = webdriver.Firefox(executable_path="geckodriver")
driver.get("https://www.google.com")
driver.find_element_by_name('q').send_keys(search_query)
time.sleep(2)
driver.find_element_by_xpath('//*[@id="tsf"]/div[2]/div[1]/div[3]/center/input[1]').send_keys(Keys.ENTER)



results = driver.find_elements_by_xpath('/html/body/div[7]/div[2]/div[10]/div[1]/div[2]/div/div[2]/div[2]/div/div/div[1]/div/div[1]/div/div[2]/span/div/ol/li/a')
    href = results.get_attribute('href')
    print(urlparse.parse_qs(urlparse(href).query)['q'])

这与您要求的条件有点接近,并且会产生您想要的结果:

MAX(CASE WHEN p.level = 1 THEN p.sid END) as l1_ancestor

Demo on DB Fiddle

sid | name | ancestors | l1_ancestor
--: | :--- | :-------- | ----------:
  1 | Root | null      |        null
  2 | A    | 1         |           2
  3 | B    | 1,2       |           2
  4 | C    | 1,2       |           2
  5 | D    | 1,2,4     |           2
  6 | E    | 1         |           6
  7 | F    | 1,6       |           6
  8 | G    | 1,6,7     |           6
  9 | H    | 1,7     |           6
 10 | I    | 1,7,9   |           6
 11 | J    | 1         |          11
 12 | K    | 1,11      |          11

相关问答

依赖报错 idea导入项目后依赖报错,解决方案:https://blog....
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下...
错误1:gradle项目控制台输出为乱码 # 解决方案:https://bl...
错误还原:在查询的过程中,传入的workType为0时,该条件不起...
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct...