父子关系表
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了父子关系表相关的知识,希望对你有一定的参考价值。
语境:
- 查询来自外部系统的事务表,以在具有两个主要列的本地系统上创建元素:
- 尚未保留在本地数据库中的子项
- 可能的多个父母分号分开(可以在本地保存或尚未创建)
我在排序看起来像这样的表时遇到问题:
Child Parents
A B;C
B C;E
C F;X
我想要完成的是确保始终在子项之前创建父:
Child Parents
C F;X
B C;E
A B;C
此示例中的F,X和E表示已存在于本地数据库中的元素,这些元素可能位于我的查询中
我花了一些时间思考这个问题,似乎它与树木/图表有关,我几乎不知道......
知道我们在这里处理什么样的排序以及可能的java或SQL实现?
编辑:
- 每个子元素都是数据库中尚未保留的元素
- 一个孩子可以有一个父母已经坚持的名单(如F,X和E)或父母我仍然需要坚持(在这种情况下他们需要先于孩子)或两者兼而有(比如B与C; E父母) E已经存在并且C进入此交易并且必须在B)之前
- 无法更改数据库,但可以在java中自由重新排序
提前致谢
部分解决方案我已经改编了Joshua的解决方案,它似乎以这种方式工作:
(基本上使用like声明,因为我们可以有类似AA的东西; BB; CC作为父亲)
SELECT DISTINCT
s1.child,
s1.parents,
CASE
WHEN s2.parents IS NULL THEN 0
WHEN s2.parents LIKE '%' + s1.child + '%' THEN 1
ELSE 3
END
AS x
FROM
sample s1
LEFT JOIN sample s2 ON s2.parents LIKE '%' + s1.child + '%'
WHERE
s1.treateddate IS NULL
ORDER BY
CASE
WHEN s2.parents IS NULL THEN 0
WHEN s2.parents LIKE '%' + s1.child + '%' THEN 1
ELSE 3
END
DESC
此解决方案不会同时考虑父母的孩子!
解决方案Java我在Java中找到了重新排序数据集的解决方案,这只是伪代码,因为我使用的是专有库...
private void sortByParentFirst(rows) {
for (int i = 0; i < rows.size(); i++) {
for (int j = 0; j < rows.size(); j++) {
boolean match = false;
//parents comma seperated at j contain child i
if (Parents[j].contains(Child[i]) ) {
match = true;
}
//this means we found an occurrence of the child i at a previous position j
if (match && j < i) {
//swap rows i & j
swap(i,j);
break;
}
}
}
}
答案
表格示例包含您的数据
select * from sample
chid parents
---- ----------
A B;C
B C;E
C F;X
select * from sample
drop table #sample
drop table #sample2
select * into #sample from sample
select * into #sample2 from sample where 1=2
alter table #sample2 add counter int
declare @count int
select @count = count(1) from #sample
declare @child char(1)
declare @counter int = 1
while(@count > 0)
begin
select @child = t1.chid
from #sample t1
inner join #sample t2 on CHARINDEX(t1.chid,t2.parents) = 0
group by t1.chid
having count( t1.chid) = 1
insert into #sample2
select *,@counter from #sample where chid = @child
delete from #sample where chid = @child
select @count = count(1) from #sample
set @counter = @counter + 1
end
select chid, parents from #sample2 order by counter
另一答案
select distinct s1.* ,
case when s2.parents is null and s3.parents is null then 0
when s1.child = left(s2.parents,1) and s3.parents is null then 1
when s1.child = right(s3.parents,1) and s2.parents is null then 2
else 3 end as x
from sample s1
left join sample s2 on s1.child = left(s2.parents,1)
left join sample s3 on s1.child = right(s3.parents,1)
order by
case when s2.parents is null and s3.parents is null then 0
when s1.child = left(s2.parents,1) and s3.parents is null then 1
when s1.child = right(s3.parents,1) and s2.parents is null then 2
else 3 end desc
将表连接回自己两次寻找与父母的匹配。如果实际日期不仅仅是一个字符,那么您可以使用CHARINDEX来定位分隔符,并根据返回的起始位置的位置左右定位每个分隔符。
以上是关于父子关系表的主要内容,如果未能解决你的问题,请参考以下文章
用于获取存储在单个表中的 n 级父子关系的 Postgresql 查询