使用TSQL从递归CTE查询中复制数据

时间:2013-01-12 21:45:49

标签: sql-server tsql recursion duplicates common-table-expression

我有以下CTE查询,如果已经派技术人员将问题解决到客户家中,我会查询。

此表包含安装之间的关系数据。它告诉我安装A是否与B链接,然后如果B与D链接,从而使A和D链接。这可以持续90个不同的条目来创建一个大的关系方案。

INIR_Id:ID

INIR_INST_Id:安装ID

INIR_INRE_Id关系ID

INIR_Date:添加关系的日期。

CREATE TABLE [dbo].[CPL_t_Installations_InstallationsRelations](
    [INIR_Id] [bigint] IDENTITY(1,1) NOT NULL,
    [INIR_INST_Id] [int] NOT NULL,
    [INIR_INRE_Id] [bigint] NOT NULL,
    [INIR_Date] [datetime] NOT NULL,
 CONSTRAINT [PK_CPL_t_Installations_InstallationsRelations] PRIMARY KEY CLUSTERED 
(
    [INIR_Id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]


WITH Tempou(Relation,Installation,Date,Origine)AS
(
    (
        SELECT
            INIR_INRE_Id,
            INIR_INST_Id,
            INIR_Date,
            1
        FROM
            CPL_t_Installations_InstallationsRelations
        WHERE
            (INIR_INST_Id=@INST_Id)
    )
    UNION ALL
    (
        SELECT
            INIR_INRE_Id,
            INIR_INST_Id,
            INIR_Date,
            0
        FROM
            CPL_t_Installations_InstallationsRelations
                INNER JOIN Tempou Alpha ON(Relation=INIR_INRE_Id)
        WHERE
            (INIR_Date<Date)
            AND NOT
            (
                (Installation=INIR_INST_Id)
                AND
                (Relation=INIR_INRE_Id)
            )
    )
)
SELECT TOP * FROM Tempou;

查询的问题是它循环回CTE结果集中的每个日期。然后每个结果都会重复多次。我使用日期作为监控数据,从无限的时间到128个条目的结果集。但是如果我们使用DISTINCT查询来自Tempou的所有内容,我们就会得到14个结果,这是正确的数字。除最好的日期数据外,没有分层数据。

我已经在这方面工作了几天,从无限的结果到128是相当不错的,但这不是答案。我可能会很累,看不出这个问题的显而易见性。让我问你所有我看不到的东西。

Ps。:我没有数据可供分享,但结果的“级别”数量没有限制,有些客户可能有2个级别,有些可能有20个。而链接数据当然不是对称的,一些“根”可能比其他的短。

谢谢!

小的补充,如果我可以用“Tempou”来做“不存在”问题就会解决,但是CTE不可能复制每个条目。所以我真的想找到一种方法来改变CTE,以便能够复制这种行为。

1 个答案:

答案 0 :(得分:0)

@ Rv3,首先关闭,SELECT TOP * FROM Tempou无法编译,但我会将其作为拼写错误

快速提问,您的CTE是否会进入无限循环?尝试在JOIN中切换它们,看它是否有效。 而不是

FROM
            CPL_t_Installations_InstallationsRelations
                INNER JOIN Tempou Alpha ON(Relation=INIR_INRE_Id)
        WHERE
            (INIR_Date < Date)
            AND NOT
            (
                (Installation=INIR_INST_Id)
                AND
                (Relation=INIR_INRE_Id)
            )

尝试

FROM
            Tempou Alpha 
                INNER JOIN  (Select * from  CPL_t_Installations_InstallationsRelations 
                            WHERE
            (INIR_Date < Date)
            AND NOT 
            (
                (Installation=INIR_INST_Id)
                AND
                (Relation=INIR_INRE_Id)
            )
            ) temp_tab
            ON(Relation=temp_tab.INIR_INRE_Id)

显然,如果您需要稍微修改以使其正常工作,我还没有尝试过这样的道歉。