假设您有一个存储有序树层次结构的平面表:
Id Name ParentId Order
1 'Node 1' 0 10
2 'Node 1.1' 1 10
3 'Node 2' 0 20
4 'Node 1.1.1' 2 10
5 'Node 2.1' 3 10
6 'Node 1.2' 1 20
Run Code Online (Sandbox Code Playgroud)
这是我们所拥有的图表[id] Name.根节点0是虚构的.
[0] ROOT
/ \
[1] Node 1 [3] Node 2
/ \ \
[2] Node 1.1 [6] Node 1.2 [5] Node 2.1
/
[4] Node 1.1.1
您将使用什么简约方法将其输出为HTML(或文本,就此而言)作为正确排序,正确缩进的树?
进一步假设你只有基本的数据结构(数组和散列图),没有带有父/子引用的花哨对象,没有ORM,没有框架,只有你的双手.该表表示为结果集,可以随机访问.
伪代码或普通英语是可以的,这纯粹是一个概念性的问题.
额外问题:在RDBMS中存储这样的树结构是否有根本更好的方法?
编辑和补充
回答一个评论者(Mark Bessey的)问题:根节点不是必需的,因为它永远不会被显示.ParentId = 0是表示"这些是顶级"的惯例.Order列定义了如何对具有相同父节点的节点进行排序.
我所谈到的"结果集"可以被描绘成一组哈希图(保留在该术语中).因为我的例子意味着已经存在.有些答案会加倍努力并首先构建它,但那没关系.
树可以任意深.每个节点可以有N个子节点.不过,我并没有考虑到"数百万条目".
不要将我选择的节点命名('Node 1.1.1')误认为是依赖的东西.节点同样可以称为"Frank"或"Bob",不暗示命名结构,这只是为了使其可读. …
可能重复:
CTE和SubQuery之间的区别?
我试图了解如何使用该WITH条款和该条款的目的WITH.
我理解的只是,该WITH条款取代了正常的子查询.
任何人都可以通过一个小例子详细解释这个问题吗?
我现在正在忙着实现一个类别的过滤器,我需要为每个"标签"生成一个INNER JOIN clausse来过滤.
问题是在一大堆SQL之后,我有一个表包含了我选择所需的所有信息,但是每次生成的INNER JOIN我都需要它
这基本上看起来像:
SELECT
*
FROM search
INNER JOIN search f1 ON f1.baseID = search.baseID AND f1.condition = condition1
INNER JOIN search f2 ON f2.baseID = search.baseID AND f2.condition = condition2
...
INNER JOIN search fN ON fN.baseID = search.baseID AND fN.condition = conditionN
Run Code Online (Sandbox Code Playgroud)
这有效,但我更喜欢"搜索"表是临时的(如果它不是一个普通的表,它可以小几个数量级),但这给我一个非常烦人的错误: Can't reopen table
一些研究引导我查看这个错误报告,但MySQL的人们似乎并不关心这样的基本功能(使用多次表)不适用于临时表.我遇到了很多关于此问题的可伸缩性问题.
有没有可行的解决方法,不需要我管理潜在的大量临时但非常真实的表或让我维护一个包含所有数据的大表?
亲切的问候,克里斯
[额外]
GROUP_CONCAT答案在我的情况下不起作用,因为我的条件是按特定顺序排列的多个列,它会使OR成为我需要的AND.但是,它确实帮助我解决了早期的问题,所以现在不再需要表格,不管是不是临时表格.我们只是想对我们的问题过于笼统.过滤器的整个应用现在已经从大约一分钟恢复到大约四分之一秒.
我有一个文件夹表,以id,parent_id关系与自身连接:
CREATE TABLE folders (
id int(10) unsigned NOT NULL AUTO_INCREMENT,
title nvarchar(255) NOT NULL,
parent_id int(10) unsigned DEFAULT NULL,
PRIMARY KEY (id)
);
INSERT INTO folders(id, title, parent_id) VALUES(1, 'root', null);
INSERT INTO folders(id, title, parent_id) values(2, 'one', 1);
INSERT INTO folders(id, title, parent_id) values(3, 'target', 2);
INSERT INTO folders(id, title, parent_id) values(4, 'child one', 3);
INSERT INTO folders(id, title, parent_id) values(5, 'child two', 3);
INSERT INTO folders(id, title, parent_id) values(6, 'root 2', null);
INSERT …Run Code Online (Sandbox Code Playgroud) 我正在自学SQL程序GalaXQL(基于SQLite)中练习练习17.我有三张桌子:
Stars包含starid;Planets包含planetid和starid;Moons包含moonid和planetid.我想要返回starid与最大数量的行星和卫星相结合的相关联.
我有一个查询将返回starid,planetid和total行星+卫星.
如何更改此查询以使其仅返回与表starid对应的单个max(total)而不是表?这是我目前的查询:
select
stars.starid as sid,
planets.planetid as pid,
(count(moons.moonid)+count(planets.planetid)) as total
from stars, planets, moons
where planets.planetid=moons.planetid and stars.starid=planets.starid
group by stars.starid
Run Code Online (Sandbox Code Playgroud) 我有一个值列表,比方说1,2,3,4,5,6.我有一个SQL表,其中一个字段存储这些值,但只有三行,比如说2,4,5.什么样的查询会1,3,6为我返回三行?(将所有六个存储在另一个表中并且左连接是作弊.)
我正在阅读这个问题如何确定 JAVA 中 jdbcTemplate 的 sql 查询类型?. 正确答案是,SELECT 查询可以以 aSELECT或 a开头WITH。
仅供参考,答案说:
// SELECT subqueries are irrelevant for the final result. So the command, the first verb is indicative of the result (int updateCount vs. ResultSet).
boolean isSqlSelect = sql.toUpperCase().startsWith("SELECT")
|| sql.toUpperCase().startsWith("WITH");
Run Code Online (Sandbox Code Playgroud)
所以,现在让我们说我有一个查询
SELECT id, name, email FROM users;
Run Code Online (Sandbox Code Playgroud)
问题
WITH?sql ×6
mysql ×4
algorithm ×1
jdbc ×1
odbc ×1
recursion ×1
sqlite ×1
temp-tables ×1
tree ×1
with-clause ×1