Sql ry,下面是自己尝试的测试数据 select a.node_name, a.node_id from test.hier a left outer join (select coo.descendant /* coo = CHI
ry,下面是自己尝试的测试数据Sql ry,下面是自己尝试的测试数据 select a.node_name, a.node_id from test.hier a left outer join (select coo.descendant /* coo = CHI,sql,tree,hierarchical-data,Sql,Tree,Hierarchical Data,ry,下面是自己尝试的测试数据 select a.node_name, a.node_id from test.hier a left outer join (select coo.descendant /* coo = CHILD OF OTHER */ from test.closure_tree coo right outer join test.closure_tree ro on coo.a
select a.node_name, a.node_id
from test.hier a left outer join
(select coo.descendant /* coo = CHILD OF OTHER */
from test.closure_tree coo right outer join test.closure_tree ro
on coo.ancestor <> ro.descendant /* ignore its self reference */
and coo.descendant = ro.descendant /* belongs to another node besides itself */)lo
on a.node_id = lo.descendant
where lo.descendant is null /* wasn't found to be a child of another node besides itself */
group by a.node_name, a.node_id
您能给出nodes选项卡的示例数据吗?感谢JJNGUY的编辑:我无法获取查询的正确格式。:)谢谢你,乔迪!我尝试了您的查询,但它以错误结束:…使用接近'3 QRY\u GROUP\u ALL'的正确语法。。。我把我的数据转储到pastebin,也许你可以试试。要理解您复杂的问题,我需要新鲜的早晨;)你好@wk我想问题可能是因为某个别名中的引号。。。我会纠正它,我会很快发布它。我会尝试解析您的查询,但MySQL不支持TOP语句。非常感谢。好啊我以前不知道,但是你可以把最上面的语句改为限制语句。。。它将是这样的:“选择QRY\u GROUP\u ALL\u OF THEM.MinAncestor,Max(QRY\u GROUP\u ALL\u OF THEM.genderant)作为maxgender LIMIT 0,3”等等……您好,我想您在最终答案(LIMIT 3)上使用了我的方法,我也认为我的答案是最优的,而不是您的方法。。。所以我认为用别人的答案创造你自己的答案是不礼貌的,没有别人给你的答案。。。这取决于你,但请确保我不会再帮你了。玩得开心…谢谢,这是个不错的主意
| ancestor | descendant | depth |
+----------+------------+-------+
| 1 | 1 | 0 |
| 1 | 2 | 1 |
| 1 | 7 | 1 |
| 1 | 8 | 2 |
| 1 | 15 | 3 |
| 1 | 16 | 3 |
| 1 | 17 | 2 |
| 2 | 2 | 0 |
| 2 | 8 | 1 |
| 2 | 15 | 2 |
| 2 | 16 | 2 |
| 2 | 17 | 1 |
| 3 | 3 | 0 |
| 3 | 4 | 1 |
| 3 | 5 | 2 |
| 3 | 6 | 1 |
| 4 | 4 | 0 |
| 4 | 5 | 1 |
| 5 | 5 | 0 |
| 6 | 6 | 0 |
| 7 | 7 | 0 |
| 8 | 8 | 0 |
| 8 | 15 | 1 |
| 8 | 16 | 1 |
| 9 | 9 | 0 |
| 9 | 12 | 1 |
| 10 | 10 | 0 |
| 10 | 14 | 1 |
| 11 | 11 | 0 |
| 11 | 13 | 1 |
| 12 | 12 | 0 |
| 13 | 13 | 0 |
| 14 | 14 | 0 |
| 15 | 15 | 0 |
| 16 | 16 | 0 |
| 17 | 17 | 0 |
SELECT c.ancestor, MAX(time) AS t
FROM closure c
JOIN nodes n ON (c.descendant = n.node AND c.ancestor <> n.node)
GROUP BY c.ancestor ORDER BY t desc;
SELECT TOP 3 QRY_GROUP_ALL_OF_THEM.MínDeancestor, Max(QRY_GROUP_ALL_OF_THEM.descendant) AS MáxDedescendant
FROM ( SELECT Min(closure.ancestor) AS MínDeancestor, [QRY_LAST_INSERTIONS].[descendant]
FROM closure, (SELECT DISTINCT closure.descendant
FROM closure
GROUP BY closure.descendant, closure.depth, closure.ancestor, closure.descendant
HAVING (((closure.descendant>12 And closure.descendant<>[closure].[ancestor]) AND (closure.depth<>0))
OR ((closure.descendant<>[closure].[ancestor]) AND (closure.depth<>0)))
) AS QRY_LAST_INSERTIONS
GROUP BY closure.descendant, [QRY_LAST_INSERTIONS].[descendant]
HAVING (((closure.descendant)=[QRY_LAST_INSERTIONS].[descendant]))
) AS QRY_GROUP_ALL_OF_THEM
GROUP BY QRY_GROUP_ALL_OF_THEM.MínDeancestor
ORDER BY Max(QRY_GROUP_ALL_OF_THEM.descendant) DESC;
SELECT TOP 3 QRY_GROUP_ALL_OF_THEM.MinAncestor, Max(QRY_GROUP_ALL_OF_THEM.descendant) AS MaxDescendant
FROM (
SELECT Min(closure.ancestor) AS MinAncestor, [QRY_LAST_INSERTIONS].[descendant]
FROM closure, (
SELECT DISTINCT closure.descendant
FROM closure
GROUP BY closure.descendant, closure.depth, closure.ancestor, closure.descendant
HAVING (((closure.descendant>12 And closure.descendant<>[closure].[ancestor])
AND (closure.depth<>0))
OR ((closure.descendant<>[closure].[ancestor]) AND (closure.depth<>0)))
) AS QRY_LAST_INSERTIONS
GROUP BY closure.descendant, [QRY_LAST_INSERTIONS].[descendant]
HAVING (((closure.descendant)=[QRY_LAST_INSERTIONS].[descendant])) ) AS QRY_GROUP_ALL_OF_THEM
GROUP BY QRY_GROUP_ALL_OF_THEM.MinAncestor
ORDER BY Max(QRY_GROUP_ALL_OF_THEM.descendant) DESC;
SELECT
QRY_GROUP_ALL_OF_THEM.MinAncestor,
Max(QRY_GROUP_ALL_OF_THEM.descendant) AS MaxDescendant LIMIT 0,3
FROM
(
SELECT
Min(closure.ancestor) AS MinAncestor,
[QRY_LAST_INSERTIONS].[descendant]
FROM closure,
(
SELECT DISTINCT closure.descendant
FROM closure
GROUP BY closure.descendant,
closure.depth,
closure.ancestor,
closure.descendant
HAVING ( ( ( closure.descendant > 12
AND closure.descendant <> [closure].[ancestor] )
AND ( closure.depth <> 0 ) )
OR ( ( closure.descendant <> [closure].[ancestor] )
AND ( closure.depth <> 0 ) ) )
) AS QRY_LAST_INSERTIONS
GROUP BY
closure.descendant,
[QRY_LAST_INSERTIONS].[descendant]
HAVING (((closure.descendant)=[QRY_LAST_INSERTIONS].[descendant]))
) AS QRY_GROUP_ALL_OF_THEM
GROUP BY QRY_GROUP_ALL_OF_THEM.MinAncestor
ORDER BY Max(QRY_GROUP_ALL_OF_THEM.descendant) DESC;
SELECT c.ancestor, MAX(n.time) AS t FROM closure c
JOIN nodes n ON (c.descendant = n.node AND c.ancestor <> n.node)
JOIN nodes n2 ON (c.ancestor = n2.node AND n2.root = 1)
GROUP BY c.ancestor ORDER BY t desc LIMIT 3;
#!/usr/bin/perl --
use strict;
use warnings;
use Data::Random qw(:all);
my ($maxnode, $node) = ();
my $dbh = !DATABASE INIT!
foreach ( 1 .. $ARGV[0] ) {
$node = ($_ == 1) ? 0 : int( rand(4) );
if (!$node) {
$maxnode = &RootNode(1);
}
else {
$maxnode = &Node($maxnode);
}
}
##
##
sub Node {
my $parent = int( rand($_[0]) ) + 1;
my $id = &RootNode(0, $parent);
my $insert = qq|INSERT INTO test.closure (ancestor, descendant, depth)
SELECT ancestor, $id, depth + 1
FROM test.closure WHERE descendant = ?|;
$dbh->do($insert, undef, $parent);
return $id;
}
##
##
##
sub RootNode {
my $min_datetime = $_[0]
? '2008-9-21 4:0:0'
: $dbh->selectrow_array( "SELECT time
FROM test.nodes WHERE node = ?", undef, $_[1] );
my $label = join( "", rand_chars( set => 'alpha', min => 5, max => 20 ) );
my $time = rand_datetime( min => $min_datetime, max => 'now' );
my $insert = qq|INSERT INTO test.nodes (label, time, root) VALUES (?, ?, ?)|;
$dbh->do($insert, undef, $label, $time, $_[0]);
my ($id) = $dbh->selectrow_array("SELECT LAST_INSERT_ID()");
$insert = qq|INSERT INTO test.closure (ancestor, descendant, depth)
VALUES (?, ?, 0)|;
$dbh->do($insert, undef, $id, $id);
return $id;
}
##
__DATA__
USE test
DROP TABLE IF EXISTS `closure`;
DROP TABLE IF EXISTS `nodes`;
CREATE TABLE `nodes` (
`node` int(11) NOT NULL auto_increment,
`label` varchar(20) NOT NULL,
`time` datetime default NULL,
`root` tinyint(1) unsigned default NULL,
PRIMARY KEY (`node`)
) ENGINE=InnoDB;
CREATE TABLE `closure` (
`ancestor` int(11) NOT NULL,
`descendant` int(11) NOT NULL,
`depth` tinyint(3) unsigned default NULL,
PRIMARY KEY (`ancestor`,`descendant`),
KEY `descendant` (`descendant`),
CONSTRAINT `closure_ibfk_1` FOREIGN KEY (`ancestor`) REFERENCES `nodes` (`node`),
CONSTRAINT `closure_ibfk_2` FOREIGN KEY (`descendant`) REFERENCES `nodes` (`node`)
) ENGINE=InnoDB;
select a.node_name, a.node_id
from test.hier a left outer join
(select coo.descendant /* coo = CHILD OF OTHER */
from test.closure_tree coo right outer join test.closure_tree ro
on coo.ancestor <> ro.descendant /* ignore its self reference */
and coo.descendant = ro.descendant /* belongs to another node besides itself */)lo
on a.node_id = lo.descendant
where lo.descendant is null /* wasn't found to be a child of another node besides itself */
group by a.node_name, a.node_id
--create table test.hier (
-- node_name varchar(10),
-- node_id int identity (1,1) primary key
--)
--insert into test.hier (node_name)
--values ('ROOT1')
--insert into test.hier (node_name)
--values ('ROOT2')
--insert into test.hier (node_name)
--values ('ROOT3')
--insert into test.hier (node_name)
--values ('ChildOf1')
--insert into test.hier (node_name)
--values ('ChildOf1')
--insert into test.hier (node_name)
--values ('ChildOf1')
--insert into test.hier (node_name)
--values ('ChildOf1')
--insert into test.hier (node_name)
--values ('ChildOf1')
--insert into test.hier (node_name)
--values ('ChildOf2')
--insert into test.hier (node_name)
--values ('ChildOf2')
--insert into test.hier (node_name)
--values ('ChildOf3')
--insert into test.hier (node_name)
--values ('ChildOf3')
--insert into test.hier (node_name)
--values ('ChildOf3')
--insert into test.hier (node_name)
--values ('ChildOf3')
--insert into test.hier (node_name)
--values ('LeafOf3')
--insert into test.hier (node_name)
--values ('LeafOf3')
--insert into test.hier (node_name)
--values ('LeafOf3')
--insert into test.hier (node_name)
--values ('LeafOf3')
--insert into test.hier (node_name)
--values ('LeafOf1')
--insert into test.hier (node_name)
--values ('LeafOf2')
--create table test.closure_tree (
-- ancestor int,
-- descendant int,
-- PRIMARY KEY (ancestor, descendant),
-- constraint fk_test_a FOREIGN KEY (ancestor) references test.hier (node_id),
-- constraint fk_test_d FOREIGN KEY (descendant) references test.hier (node_id)
--)
-- SELF REFERENCES
--insert into test.closure_tree (ancestor, descendant)
--select node_id as a, node_id as d
--from test.hier
--insert into test.closure_tree (ancestor, descendant)
--select a.node_id, b.node_id
--from test.hier a join test.hier b
-- on a.node_name = 'ROOT1'
-- and b.node_name = 'ChildOf1'
--insert into test.closure_tree (ancestor, descendant)
--select a.node_id, b.node_id
--from test.hier a join test.hier b
-- on a.node_name = 'ROOT2'
-- and b.node_name = 'ChildOf2'
--insert into test.closure_tree (ancestor, descendant)
--select a.node_id, b.node_id
--from test.hier a join test.hier b
-- on a.node_name = 'ROOT3'
-- and b.node_name = 'ChildOf3'
--insert into test.closure_tree (ancestor, descendant)
--select a.node_id, b.node_id
--from test.hier a join test.hier b
-- on a.node_name = 'ChildOf3'
-- and b.node_name = 'LeafOf3'
--insert into test.closure_tree (ancestor, descendant)
--select a.node_id, b.node_id
--from test.hier a join test.hier b
-- on a.node_name = 'ROOT3'
-- and b.node_name = 'LeafOf3'
--insert into test.closure_tree (ancestor, descendant)
--select a.node_id, b.node_id
--from test.hier a join test.hier b
-- on a.node_name = 'ROOT1'
-- and b.node_name = 'LeafOf1'
--insert into test.closure_tree (ancestor, descendant)
--select a.node_id, b.node_id
--from test.hier a join test.hier b
-- on a.node_name = 'ChildOf1'
-- and b.node_name = 'LeafOf1'
--insert into test.closure_tree (ancestor, descendant)
--select a.node_id, b.node_id
--from test.hier a join test.hier b
-- on a.node_name = 'ChildOf2'
-- and b.node_name = 'LeafOf2'
--insert into test.closure_tree (ancestor, descendant)
--select a.node_id, b.node_id
--from test.hier a join test.hier b
-- on a.node_name = 'Root2'
-- and b.node_name = 'LeafOf2'
---- Test read of hierarchy with weird ordering for human readability
--select a.node_name, b.node_name as descendant_node_name
--from test.hier a join test.closure_tree c
-- on a.node_id = c.ancestor
-- join test.hier b
-- on c.descendant = b.node_id
--order by right(a.node_name, 1), left(a.node_name, 1) desc
select x.ancestor
from nodes n
join closure c on (c.descendant = n.node)
join (
-- all root node
select ancestor
from closure
group by descendant
having count(*) = 1
) x ON x.ancestor = c.ancestor
where c.depth = 1
order by n.time desc
limit 3