更快的方法来检索SQL中的父值

时间:2018-02-16 17:38:56

标签: sql sql-server join

以下是我对虚拟数据的问题的描述:

我在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

只是想知道是否有更好的方法来做到这一点。 谢谢!

3 个答案:

答案 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上添加非唯一索引可以加快速度。