选择有最多孙辈的人的名字

发布于 2024-09-11 18:29:47 字数 1387 浏览 2 评论 0原文

我有一张简单的桌子,但还有一个额外的
田野女巫持有父亲/母亲的信息(人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独立答案

I have a simple table with persons, but there is a additional
field witch holds information (person id) who is a father/mother
of that person, so the 2 dimensional table can hold a familly tree

the table is

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  

The task is to select person name which has biggest number of grandchildren

All I managed to do is:

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

and the result is

first_name last_name grandchilds
Steven King 2
Alexander Khoo 5

please help :)
ps: I would like to get RDBMS independent answer if it is possible

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

成熟稳重的好男人 2024-09-18 18:29:47

我想我做到了,请看一下我的解决方案并评论它

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”所说

I think I did it, please take a look at my solution and comment it

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);

edit: I fixed it up as 'onedaywhen' said

薄荷→糖丶微凉 2024-09-18 18:29:47

以下是 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%你想要的。

The following is an ANSI solution except for the strpos function (which is PostgreSQL specific). But it shouldn't be hard to find the correct function that finds a substring in another string.

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) 

I tested this with PostgreSQL, but it should also work on Firebird, SQL Server, DB2, Oracle 11gR2 and Teradata. Not all of them accept the (according to the standard) mandatory keyword recursive, so you might need to remove that depending on the target DBMS.

SQL Server breaks the standard by not using || for string concatenation. You must use + instead.

Edit:

Just noticed that it will count all children not only the grandchildren, so it's not 100% what you want.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文