【问题标题】:Duplicate data from a recursive CTE query using TSQL使用 TSQL 从递归 CTE 查询中复制数据
【发布时间】:2013-01-12 21:45:48
【问题描述】:

如果技术人员已被派往客户家解决问题,我有以下 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”来执行“NOT EXISTS”,问题就会得到解决,但使用复制每个条目的 CTE 是不可能的。所以我真的想找到一种方法来改变 CTE,以便能够复制这种行为。

【问题讨论】:

  • 为您的联接添加别名并在所有引用上使用它们可能会让我们更好地了解您正在尝试做什么。向我们展示表模式也会有所帮助。
  • 至少一个问题 "INNER JOIN CPL_t_Installations_InstallationsRelations ON(INIR_INRE_Id=INRE_Id)" INIR_INRE_Id of which table, INRE_Id of which table ....
  • @bummi 我更新了查询以更正它。那个 sn-p 代码现在应该已经存在了,我很可能上传了一个我正在玩弄的版本。

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


【解决方案1】:

@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)

显然我还没有尝试过运行它,所以如果您需要修复一点以使其正常工作,我们深表歉意。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-08-11
    • 2014-08-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-12-07
    相关资源
    最近更新 更多