问题描述
我有一个嵌套集树,我正在搜索一个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
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