以下是我对虚拟数据的问题的描述:
我在SQL Server中有一个表,如下所示: 表
id parentid extid Isparent
0 a m 0
1 a m 1
2 a s 0
3 a s 0
4 b q 1
5 b z 0
对于具有相同parentid的每组记录,只有一条Isparent = 1的记录。
对于每条记录,我想找到他们父母的ex。
因此,对于id = 0,父记录是id = 1,而id = 1的extid = m是我需要的值。
这是我想要的输出。
childid parentid child_extid parent_extid
0 a m m
1 a m m
2 a s m
3 a s m
4 b q q
5 b z q
我是通过自我加入来做这件事的,但由于表格很大,性能非常慢,我还需要多次为几个不同的表格执行此操作,这会让事情变得更糟。
SELECT
a.Id AS 'ChildId',
a.parentid As 'ParentId',
a.extid AS 'child_extid ',
b.extid AS 'parent_extid '
FROM Table a
LEFT JOIN Table b ON (a.parentid = b.parentid)
WHERE b.isparent = 1
只是想知道是否有更好的方法来做到这一点。 谢谢!
答案 0 :(得分:0)
这种设计方法非常不正统。这种结构不仅不能代表真正的层次结构,而且它似乎也代表了三元关系,而不是二元关系。如果您可以控制此数据的设计,并且这不是您的意图,我可以根据需要帮助您重新格式化您的意图。在此之前,这是您可能正在寻找的内容的一个非常基本的表示,但是由于存在关于数据意图的未解答的问题,例如如果您生成具有值ParentID = a,ExitID =的值的行,则会出现问题。 y,IsParent = 1?
话虽如此,这里有一个裂缝。请注意,此执行将是自半连接,并且需要索引才能正常工作。由于上述问题,这也排除了order by子句。
以下代码将采用TSQL格式,直到明确DBMS为止。
CREATE FUNCTION ParentExitID (@ChildID INT)
AS
BEGIN
RETURN (
SELECT TOP 1 a.ParentID
FROM SampleTable A
WHERE EXISTS (
SELECT 1
FROM SampleTable B
WHERE A.ParentID = B.ParentID
AND A.IsParent = 1
AND B.ChildID = @ChildID
)
END
答案 1 :(得分:0)
"更快"方法是关系地使用关系数据库,并在设计中采用规范化。问题的证明是在没有任何规范化的情况下尽可能地填入表中,然后在其上构建复杂(且效率低下)的查询逻辑。
IServiceProvider sp = services.BuildServiceProvider();
在原始问题的复杂性中变得混乱的是extid依赖于父主键,但它不依赖于子主键。模型必须反映出来。
答案 2 :(得分:0)
不确定它是否会真正加快速度。 但是你可以在没有WHERE子句的情况下运行它,方法是将该条件放在JOIN中的b.isparent上。
使用表变量的示例:
declare @Table table (id int identity(0,1) primary key, parentid varchar(30), extid varchar(30), isparent bit);
insert into @Table (parentid, extid, isparent) values
('a','m',0),
('a','m',1),
('a','s',0),
('a','s',0),
('b','q',1),
('b','z',0);
SELECT
a.Id AS 'ChildId',
a.parentid AS 'ParentId',
a.extid AS 'child_extid',
b.extid AS 'parent_extid'
FROM @Table a
LEFT JOIN @Table b ON (a.parentid = b.parentid and b.isparent = 1);
但解释计划可能与您的查询中的相同 在parentid上添加非唯一索引可以加快速度。