我已经对这个问题进行了几乎完全的重写,因为我仍然坚持......寻找一种方法来查看结果表中的数据,而无需使用php或其他数据翻译/编程,看看结果我想看到它们。
基本结果表就像这样(如果你愿意,可以混淆它):
id1 | id2 | name | ord
------------------------------
a1 | null | name1 | 0
a2 | null | name2 | 1
a3 | null | name3 | 2
b1 | a1 | name4 | 0
b2 | b1 | name5 | 0
b3 | a1 | name6 | 1
b4 | a1 | name7 | 2
c1 | a2 | name8 | 0
c2 | a2 | name9 | 1
d1 | a2 | name10 | 2
d2 | a2 | name11 | 3
d3 | a2 | name12 | 4
d4 | a3 | name13 | 0
c3 | d4 | name14 | 0
c4 | c3 | name15 | 1
d5 | b2 | name16 | 0
我正在寻找的结果是:
id1 | id2 | name | ord
-----------------------------
a1 | null | name1 | 0 <--group header, signified by `id2` is null
b1 | a1 | name4 | 0 <--item that's parent to line below
b2 | b1 | name5 | 0 <--item that's parent to line below
d5 | b2 | name16 | 0 <--last child item
b3 | a1 | name6 | 1 <--special case where `ord` takes over
b4 | a1 | name7 | 2 <--`id2` is still the same, so `ord` sort
a2 | null | name2 | 1 <--next group header
c1 | a2 | name8 | 0 <--`id2` is a2, so name2 is parent, `ord` sort
c2 | a2 | name9 | 1 <--same
d1 | a2 | name10 | 2 <--same
d2 | a2 | name11 | 3 <--same
d3 | a2 | name12 | 4 <--same
a3 | null | name3 | 2 <--next group header
d4 | a3 | name13 | 0 <--`id2` is a3, so name3 is parent
c3 | d4 | name14 | 0 <--`id2` is d3, so name13 is parent
c4 | c3 | name15 | 1 <--`id2` is c3, so name14 is parent
对我需要的解释
基本上,我需要id2
成为&#34;群组标题&#34;按ord
排序。然后在每个行的下方,我需要对行进行排序,使得id2
等于其上方行的id1
,并且任何时候id2
都与{{1}相同对于它上面的行,它应该按id2
排序。
如果ord
与上一个id2
匹配的行数不足,则应显示下一个组标题,并且应在下一个id1
匹配{{1}时重新开始排序新组标题。
id2
为空的任何项都是一个组标题,但在这些组中,id1
根据&#34; parent&#34;重新开始。线。其中一些行也是其他项目的父项,因此排序的复杂性
实际结果表中还有其他列,因此我将其简化为实际排序所需的列。
解释表数据
实际的id2
列是char(36),ord
是varchar(1024),id
是int(11),表中的其他列运行色域。 ..我还应该提一下,这些结果来自name
这样做是为了限制找到这些数据的主表的结果。
ord
是主键且唯一,与排序顺序无关,除了JOIN
等于给定id1
组标题的所有行都应该出现在它下面。
id2
是对&#34;父线ID&#34;的引用。因此,为什么它对于组头是空的;他们是最父级的行,并通过id1
拥有自己的排序顺序。
id2
实际上是组标题行所期望的项目名称。
例如,假设群组标题是食物组,其他条目是食物类型。因此,一个组头将是#34; fruit,&#34;下一个&#34;蔬菜,&#34;它实际上是A / V装备,但水果可能更容易理解。
我做了什么
我对此的尝试已遍布整个地图。我已经尝试了各种ord
,name
,order by
,并且我已经考虑了子查询,但我的技能不仅仅是在我的拥有。我想如果我能指出正确的方向,我可以把我所拥有的东西结合起来得到正确的结果。不幸的是,出于沮丧,我删除了任何半工作代码,但它可能只是一个field()
带有不起作用的if()
语句。
要点:
ORDER BY
为空时,它是一个组标题,组标题应按其CASE
字段从最低到最高(0,1,2)排序。id2
等于另一行&#39; s ord
的任何行都是其父级。换句话说,如果找到一行id1
等于另一行的id2
,则应将其置于其下方。id2
等于id1
,则排序应首先考虑#2,然后按id2
排序从最低到最高。答案 0 :(得分:1)
您描绘的数据是层次结构(id2指的是“父”),而MySQL(直到5.7的东部)没有特定的功能,例如处理层次结构的递归CTE。有工作和这里,我们似乎知道我们可以使用一个左连接的最大级别数(级别-1)(即4个级别添加3个左连接)。一旦通过连接建立了层次结构,然后在各个列中使用COALESCE(),由于左连接,其中许多现在可以为NULL,我们可以安排数据以适合所需的排序顺序。 (好“差不多”。如果你将想要的订单与下面的查询所示的订单进行比较,那么会有一些细微差别。)
请参阅此SQL Fiddle。
CREATE TABLE Table1
(`id1` varchar(2), `id2` varchar(4), `name` varchar(6), `ord` int)
;
INSERT INTO Table1
(`id1`, `id2`, `name`, `ord`)
VALUES
('a1', NULL, 'name1', 0),
('a2', NULL, 'name2', 1),
('a3', NULL, 'name3', 2),
('b1', 'a1', 'name4', 0),
('b2', 'b1', 'name5', 0),
('b3', 'a1', 'name6', 1),
('b4', 'a1', 'name7', 2),
('c1', 'a2', 'name8', 0),
('c2', 'a2', 'name9', 1),
('d1', 'a2', 'name10', 2),
('d2', 'a2', 'name11', 3),
('d3', 'a2', 'name12', 4),
('d4', 'a3', 'name13', 0),
('c3', 'd4', 'name14', 0),
('c4', 'c3', 'name15', 1),
('d5', 'b2', 'name16', 0)
;
<强>查询强>:
select
coalesce(p1.id1, p2.id1, p3.id1, p4.id1) id1s
, coalesce(p1.id2, p2.id2, p3.id2, p4.id2) id2s
, coalesce(p1.name, p2.name, p3.name, p4.name) names
, coalesce(p1.ord, p2.ord, p3.ord, p4.ord) ords
#, coalesce(p4.id1, p3.id1, p2.id1, p1.id1) ord1
#, coalesce(p4.id2, p3.id2, p2.id2, p1.id2) ord2
#, coalesce(p4.ord, p3.ord, p2.ord, p1.ord) ord3
from table1 p1
left join table1 p2 on p1.id2 = p2.id1
left join table1 p3 on p2.id2 = p3.id1
left join table1 p4 on p3.id2 = p4.id1
order by
coalesce(p4.id1, p3.id1, p2.id1, p1.id1)
, coalesce(p4.id2, p3.id2, p2.id2, p1.id2)
, coalesce(p4.ord, p3.ord, p2.ord, p1.ord)
, id2s
<强> Result 强>:
| id1s | id2s | names | ords |
|------|--------|--------|------|
| a1 | (null) | name1 | 0 |
| b3 | a1 | name6 | 1 |
| b4 | a1 | name7 | 2 |
| b1 | a1 | name4 | 0 |
| b2 | b1 | name5 | 0 |
| d5 | b2 | name16 | 0 |
| a2 | (null) | name2 | 1 |
| d3 | a2 | name12 | 4 |
| c2 | a2 | name9 | 1 |
| d1 | a2 | name10 | 2 |
| d2 | a2 | name11 | 3 |
| c1 | a2 | name8 | 0 |
| a3 | (null) | name3 | 2 |
| d4 | a3 | name13 | 0 |
| c4 | c3 | name15 | 1 |
| c3 | d4 | name14 | 0 |
<强>想强>:
# id1 | id2 | name | ord
# -----------------------------
# a1 | null | name1 | 0 <--group header, signified by `id2` is null
# b1 | a1 | name4 | 0 <--item that's parent to line below
# b2 | b1 | name5 | 0 <--item that's parent to line below
# d5 | b2 | name16 | 0 <--last child item
# b3 | a1 | name6 | 1 <--special case where `ord` takes over
# b4 | a1 | name7 | 2 <--`id2` is still the same, so `ord` sort
# a2 | null | name2 | 1 <--next group header
# c1 | a2 | name8 | 0 <--`id2` is a2, so name2 is parent, `ord` sort
# c2 | a2 | name9 | 1 <--same
# d1 | a2 | name10 | 2 <--same
# d2 | a2 | name11 | 3 <--same
# d3 | a2 | name12 | 4 <--same
# a3 | null | name3 | 2 <--next group header
# d4 | a3 | name13 | 0 <--`id2` is a3, so name3 is parent
# c3 | d4 | name14 | 0 <--`id2` is d3, so name13 is parent
# c4 | c3 | name15 | 1 <--`id2` is c3, so name14 is parent
答案 1 :(得分:1)
已经有一段时间了。老实说,我已经忘记了它代表的意思,但是我相信我试图对订单项在应用程序中的显示进行排序。假设情况如此,我从一位开发人员那里得到了答案。我们最终使用了COALESCE()
和LPAD()
的组合。
说这些是列表中的订单项,但有些是嵌套的,它们都位于同一表中。唯一的关系是知道父行的id
和ordinal
。我们想到了这个:
SELECT CONCAT_WS('-', LPAD(COALESCE(item5.ordinal),4,'0'),`
LPAD(COALESCE(item4.ordinal),4,'0'),
LPAD(COALESCE(item3.ordinal),4,'0'),
LPAD(COALESCE(item2.ordinal),4,'0'),
LPAD(COALESCE(item.ordinal),4,'0')) AS line_order
FROM main_lines as main
LEFT JOIN sub_line as item on item.id = main.id
LEFT JOIN sub_line as item2 on item2.id = item.parent_line_id
LEFT JOIN sub_line as item3 on item3.id = item2.parent_line_id
LEFT JOIN sub_line as item4 on item4.id = item3.parent_line_id
LEFT JOIN sub_line as item5 on item5.id = item4.parent_line_id
ORDER BY line_order;
COALESCE
允许我们对行进行空安全保护,而LPAD
则允许CONCAT_WS
提供正确的排序顺序,并在每个结果中使用0。