Sql 选择孙辈最多的人的姓名
我有一个简单的人员表,但还有一个额外的Sql 选择孙辈最多的人的姓名,sql,database,select,hierarchical-data,Sql,Database,Select,Hierarchical Data,我有一个简单的人员表,但还有一个额外的 字段witch保存作为父亲/母亲的信息(个人id) 所以二维表格可以容纳一棵家族树 桌子是空的 id first_name last_name salary spouse_id father_id mother_id sex 100 Steven King 26400 101 (null) (null) m 101 Neena Kochhar 18700 100 (null) (null) f 102 Lex De Haan 18700 106
字段witch保存作为父亲/母亲的信息(个人id)
所以二维表格可以容纳一棵家族树 桌子是空的
id first_name last_name salary spouse_id father_id mother_id sex
100 Steven King 26400 101 (null) (null) m
101 Neena Kochhar 18700 100 (null) (null) f
102 Lex De Haan 18700 106 100 101 m
103 Alexander Hunold 9900 (null) 100 101 m
104 Bruce Ernst 6600 (null) 102 106 m
105 David Austin 5280 (null) 102 106 m
106 Valli Pataballa 5280 102 (null) (null) f
107 Diana Lorentz 4620 (null) (null) (null) f
108 Nancy Greenberg 13200 109 (null) (null) f
109 Daniel Faviet 9900 108 115 116 m
110 John Chen 9020 (null) 109 108 m
111 Ismael Sciarra 8470 (null) 109 108 m
112 Jose Manuel Urman 8580 (null) 109 108 m
113 Luis Popp 7590 (null) 109 108 m
114 Den Raphaely 12100 (null) 109 108 m
115 Alexander Khoo 3410 116 (null) (null) m
116 Shelli Baida 3190 115 (null) (null) f
任务是选择孙辈人数最多的人名
我所能做的就是:
select
e1.first_name, e1.last_name
--,max (e3.first_name)
,count(e3.first_name) grandchilds
from empnew e1
inner join
empnew e2
on (e1.id = e2.father_id)
inner join
empnew e3
on (e2.id = e3.father_id)
group by e1.first_name, e1.last_name
结果是
first_name last_name grandchilds
Steven King 2
Alexander Khoo 5
请帮忙:)
ps:如果可能的话,我想得到独立于RDBMS的答案,我想我做到了,请查看我的解决方案并发表评论
SELECT
e1.first_name
, e1.last_name
, count(e3.first_name) AS grandchilds
FROM empnew e1
INNER JOIN
empnew e2
ON (e1.id = e2.father_id)
INNER JOIN
empnew e3
ON (e2.id = e3.father_id)
GROUP BY e1.first_name, e1.last_name
HAVING COUNT(e3.first_name)
=
(SELECT MAX (grandchilds) FROM
(
SELECT
e1.first_name
, COUNT(e3.first_name) AS grandchilds
FROM empnew e1
INNER JOIN
empnew e2
ON (e1.id = e2.father_id)
INNER JOIN
empnew e3
ON (e2.id = e3.father_id)
GROUP BY e1.first_name
) table_1);
编辑:我把它改成了“onedaywhen”,上面说了以下是一个ANSI解决方案,除了
strpos
函数(特定于PostgreSQL)。但要找到在另一个字符串中找到子字符串的正确函数应该不难
with recursive person_tree as (
select id, first_name, last_name, cast(id as varchar)||'/' as id_path, id as root_id
from persons
where father_id is null
union all
select c.id, c.first_name, c.last_name, id_path || cast(c.id as varchar)||'/', null
from persons c
join person_tree p on c.father_id = p.id
),
group_flags as (
select id_path,
id,
first_name,
last_name,
substring(id_path, 0, strpos(id_path, '/')) as root_id
from person_tree
)
select root_id, count(*)
from group_flags
group by root_id
having count(*) = (select max(children_count)
from (select root_id,
count(*) as children_count
from group_flags
group by root_id
) t)
我用PostgreSQL对此进行了测试,但它也应该适用于Firebird、SQL Server、DB2、Oracle 11gR2和Teradata。并非所有数据库都接受(根据标准)强制关键字recursive
,因此您可能需要根据目标DBMS删除该关键字
SQL Server违反了标准,没有使用|
进行字符串连接。您必须改用+
编辑:
只是注意到它会计算所有的孩子,而不仅仅是孙子,所以它不是你想要的100%。你忘记了母亲。(因为你没有单亲父母,所以这对你来说可能不太重要)。如果这是家庭作业,请给它贴上这样的标签。你可以忘记母亲(母亲id)-这会更容易,没有母亲我也可以做。SQL Server(最常用的SQL产品之一)不起作用但是可以通过给派生表一个相关名称来修复,例如将
)
替换为)作为DT1)
…老实说,如果您想要一个独立于SQL产品的答案,为什么不编写符合SQL-92标准的SQL:大写关键字(选择而不是选择),使用AS
关键字作为相关名称(empnew AS e1
而不是empnew e1
和COUNT(e3.first_name)作为孙子
而不是COUNT(e3.first_name)孙子
),以分号结束语句代码>。说实话,我不知道!:)fwiw、SQL关键字不要求为大写。