我有一个具有这种结构的表
id integer
parent_id integer
order_n integer
info text
每行可以有一个父行(parent_id,如果没有父行,则为null)和一个插入顺序(order_n)。每次插入一行时,order_n字段将被设置为相关的“在他的父母内部”。因此,第一级的两行将是order_n = 1而order_b = 2.但是第一行“内部”的新行将是order_n = 1
实施例
id parent_id order_n info
1 null 1 "Beatles"
2 null 2 "Stones"
3 1 1 "Paul"
4 1 2 "John"
5 2 1 "Mick"
6 2 2 "Keith"
子级别是无限的。
我正在尝试做的事情(我悲惨地失败)是查询谁检索任何级别(包括第一级)的所有行,并根据他的order_n属性对其进行排序,但是对嵌套进行分组行。例如,在前面的示例中,我们需要以这种方式检索结果
1 null 1 "Beatles"
3 1 1 "Paul"
4 1 2 "John"
2 null 2 "Stones"
5 2 1 "Mick"
6 2 2 "Keith"
我正在努力尝试但我对SQL知之甚少,我会事先感谢你所有明智的建议。
我正在使用MySQL,但理想的是尝试“sql standard”
内在水平是无限的。
答案 0 :(得分:1)
直到你的最后一行“内在水平是无限的”,这不是一个难以写的问题。您将为自己所需的每个级别加入表格。如果预定义的最大值为5级,则可以将表连接到自身5次(左连接)以实现此目的。
非常伪造的代码:
Select whatever
from mytable my1
left join mytable my2 on my1.id = my2.parent_id
where whatever
order by case when parent_id is null then id else parent_id end,
case when parent_id is null then 0 else order_n end
order by子句中的case语句旨在识别顶级父记录,并将其与其余记录分组。
想要更多级别?扩展join语句: 在my2.id = my3.parent_id上加入mytable my3 在my3.id = my4.parent_id上加入mytable my4 在my4.id = my5.parent_id
上加入mytable my5没有'最大'数量的级别,根据马修PK的动态SQL是(据我所知)你唯一的追索权。
my1,my2,my3等也可能不是最简单的别名命名约定,选择你可以遵循的内容。
答案 1 :(得分:0)
这将是动态SQL,并且有点复杂。
我们需要更多细节来确定对此的帮助,但它将从以下开始:
您需要确定查询的深度行数,否则会冒无限循环的风险。
确定每行所需的列
基本上,您将在存储过程中创建一个varchar,它将根据您的查询需要增长。
您需要在此查询中将变量设置为最高的n顺序,然后循环,为每个嵌套表添加列,连接,顺序,组和(最重要的!)别名。
这是一些伪代码:
int maxval = 0
select maxval = max(n-level) from table where ...
string newalias = ""
string oldalias = newguid
int cnt = 0
int parentid = NULL
string selectstatement = "select "
string joinstatement = "from table as" oldalias
string orderstatement = "order by"
while cnt < maxval
newalias = newguid
selectstatement = selectstatement + "," + newalias + "." + columnnames
joinstatement = joinstatement + " JOIN table as " + newalias + "on " + newalias + ".columnname = " + oldalias + ".columname"
orderstatement = orderstatement + "," + newalias + ".columnname"
maxval = maxval + 1
oldalias= newalias
loop