父 ID 不在列表中时递归 CTE

2024-03-11

我有以下嵌套集

结果就是这棵树

1 -
  |---- 2 -
  |       |---- 4 -
  |               |---- 7
  |               |---- 8
  |----10 -
          |---- 9
3 -
  |----  5
  |----  6
13-
  |---- 11
  |---- 12

我有一份产品清单 选择 ID、名称... 来自产品

与类别的多对多关系。所有类别都可以有促销活动。好吧,现在问题来了。

假设我有一个类别 7、8、6 的 ProductX。以及类别 1、2、3 中的促销活动。我需要让最接近的父母按类别进行促销,或者直到没有更多的父母为止。

最终结果应该是

CategoryId PromotionPrice
    2          price...
    3          price...

我拥有的

WITH Promotions (CategoryId, PromotionPrice)
{
    SELECT CategoryId, PromotionPrice
    FROM Promotions
}
SELECT CategoryId, PromotionPrice
FROM NestedSet s1
    LEFT JOIN NestedSet s2 ON s1.ParentId = s2.Id
    LEFT JOIN Promotions p ON s1.CategoryId = p.CategoryId

然后获得更好的促销(我知道该怎么做)并应用于主查询 SELECT * FROM Products;对于每个产品(所以只是一个简单的连接)。

我的问题是我知道我需要使用(或者我认为我需要使用)递归 CTE,但我不知道该怎么做。因为它应该只对每一行递归,并且直到找到该行的促销为止。

编辑(我会尝试解释逻辑)。

ProductId  CategoryId
     1         7
     1         8
     1         6

该产品有 2 个直接父级:4(来自 7 和 8)和 3(来自 6) 我的 CategoryIds 有促销活动:1、2、3。 第一轮查询结果

CategoryId ParentId PromotionPrice
     7         4         NULL
     8         4         NULL 
     6         3          10

重要的是 ParentId,这样我就可以 GroupBy ParentId,结果是

CategoryId PromotionPrice
     4         NULL
     3          10

好的,由于 PromotionPrice 为 NULL,我需要转到他的父项(在本例中为 2),因此上面的查询需要返回

CategoryId ParentId PromotionPrice
     4       2         NULL
     3      NULL       10

由于 PromotionPrice 为 Null,我必须检查 Category2 是否有促销,因此结果为

CategoryId ParentId PromotionPrice
     2       1         15
     3      NULL       10

它停在那里。如果我从类别 2 中删除促销活动,则应该进行另一轮:

CategoryId ParentId PromotionPrice
     1      NULL       5
     3      NULL       10

此时,由于不再有父级,因此 PromotionPrice 是否为 null 并不重要。问题是我需要一路努力才能获得晋升。

当我查看 SortPath 时已经拥有所有信息,只需要将其分解并递归向后直到找到具有促销的 ID,但我仍然不知道如何实现这一点。

希望这有助于解释一下。


注意:我稍作编辑以反映您提供的示例数据。

设置

这是我必须代表您的嵌套集的内容:

declare @nestedSet table (
    id int,
    parentId int
);

insert @nestedSet values 
    (1, null), (2, 1), (4, 2), (7, 4), (8, 4), (10, 1), (9, 10), (1004, 1),
    (3, null), (5, 3), (6, 3),
    (13, null), (11, 13), (12, 13);

以下是我为您的促销活动构建的内容:

declare @promotions table (
    promotionId int identity(1,1),
    categoryId int,
    price float
);

insert @promotions values (1, 5), (2, 15), (3, 10);

还有您的产品,我已将其重命名为 ProductCategories 以更好地反映其内容:

declare @productCategories table (productId int, categoryId int);
insert @productCategories values (1,7),(1,8),(1,6);

解决方案

作为主播,我只是拉入了产品表。但我认为在您的用例中,您需要一个过滤器来挑选合适的基础产品。然后我做了一个计算来检查该类别是否已经是促销活动。如果是,那么它代表一个叶节点。

在递归中,我只是将每个不是叶子的节点的嵌套集的层次结构向上移动。我再次计算一下该类别是否是促销,看看它是否是叶子节点。

从结果中,我选择了所有叶节点,按价格排序,并输出最上面的一个。

declare @productId int = 1;

with

    traverse as (

        select      categoryId, 
                    parentId, 

                    isLeaf = iif(exists (
                        select 0  
                        from @promotions pm 
                        where pd.categoryId = pm.categoryId
                    ), 1, 0)

        from        @productCategories pd
        join        @nestedSet n on pd.categoryId = n.id
        where       pd.productId = @productId 

        union all
        select      categoryId = par.id,
                    par.parentId,

                    isLeaf = iif(exists (
                        select 0 
                        from @promotions pm 
                        where par.id = pm.categoryId
                    ), 1, 0)

        from        traverse pd
        join        @nestedSet par on pd.parentId = par.id
        where       pd.isLeaf = 0

    )


    select      
    top 1       p.*
    from        traverse t
    join        @promotions p on t.categoryId = p.categoryId
    where       isLeaf = 1
    order by    p.price
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

父 ID 不在列表中时递归 CTE 的相关文章

  • 如何返回以列名作为第一行的 T-SQL 查询

    我正在编写一个 SSIS 包来将数据从 SQL Server 2012 数据库输出到 CSV为客户归档 要求是第一行是列名称 下面是我为数据流任务中的源编写的查询 问题是 它总是将列名返回为最后一行 而不是第一行 为什么 我该如何实现这一目
  • 如何在sql中查询xml列

    我在 SQL Server 2008 上有一个表 T1 其中包含一个 XML 列 EventXML 我想查询某个节点包含特定值的所有行 更好的是 我想检索不同节点中的值 表T1 T1 EventID int EventTime dateti
  • 如何从 SQL Server 2005 备份中恢复单个表?

    我已经使用常规 SQL Server 2005 备份命令进行了备份 有没有办法只恢复单个表 而不是整个数据库 将整个数据库恢复到另一台机器 或临时数据库 然后复制表对我来说似乎是最简单的
  • 将插入与 select 语句合并

    这对我有用 MERGE Table1 AS tgt USING SELECT TOP 1 FROM Table2 SELECT itmid FROM Table3 WHERE id id as a WHERE id id AS src ON
  • 触发器以捕获服务器中的架构更改

    是否可以实现类似以下触发器的东西 CREATE TRIGGER tr AU ddl All Server ON DATABASE WITH EXECUTE AS self FOR DDL DATABASE LEVEL EVENTS AS D
  • 如何在 SQL Server 查询中的 FROM 子句中使用变量?

    我正在创建一个查询 该查询将选择表中的所有数据 查询将根据我将传递给存储过程的变量选择表 在我的例子中 如果我执行example sp table1它将选择table1 如果我使用同样的事情example table table2 应该选择
  • 选择表中的人员并排除妻子,但合并他们的名字

    我有一张桌子Person PersonID FirstName LastName 1 John Doe 2 Jane Doe 3 NoSpouse Morales 4 Jonathan Brand 5 Shiela Wife And a R
  • SSIS ForEach File 循环 - 将文件名插入表

    我正在构建一个 SSIS 包 使用 VS 2017 来从特定文件夹加载一堆 CSV 文件 使用 ForEach File 循环效果很好 数据流任务具有平面文件源和 OLE DB 目标 我希望能够将文件名以及 CSV 文件中的数据保存在同一个
  • SQL Server:将 varchar 转换为十进制(也考虑指数表示法)

    我需要转换表的数据并进行一些操作 其中一种列数据类型是Varchar 但它存储decimal数字 我正在努力转换varchar into decimal 我努力了CAST TempPercent1 AS DECIMAL 28 16 问题是数
  • 当我尝试连接到数据库时收到“错误:无法初始化 OLE”? C#

    我正在尝试通过 C 连接到数据库 但这样做时收到一条非常无用的错误消息 08 44 17 错误 无法初始化 OLE 08 44 17 错误 无法初始化 OLE 我尝试寻找解决方案 但没有成功 我也尝试重新启动计算机 但这也没有帮助 我正在运
  • SQL查询多行变成单行

    有什么方法可以将通常返回具有相同值的多行的 SQL 查询更改为单行吗 例如 如果我现有的查询返回以下内容 ColA ColB 1 AA 1 BB 1 CC 2 AA 3 AA 我可以将查询更改为仅返回 3 行 并将 1 的第二个和第三个结果
  • SQL 解析键值字符串

    我有一个像这样的逗号分隔字符串 key1 value1 key2 value2 key3 value3 key1 value1 1 key2 value2 1 key3 value3 1 我想将它解析成一个如下所示的表 Key1 Key2
  • C# 事务中的事务

    我正在使用 C 将发票的平面文件导入到数据库中 如果遇到问题 我将使用 TransactionScope 回滚整个操作 这是一个棘手的输入文件 因为一行不一定等于一条记录 它还包括链接记录 发票将包含标题行 行项目和总计行 有些发票需要跳过
  • 如何跟踪数据库连接泄漏

    我们有一个应用程序似乎存在连接泄漏 SQL Server 表示已达到最大池大小 我独自一人在我的开发机器上 显然 只需导航应用程序 我就会触发此错误 SQL Server 活动监视器显示大量正在使用我的数据库的进程 我想查找哪些文件打开连接
  • 游标与更新

    一家公司使用 SQL Server 数据库来存储有关其客户及其业务交易的信息 您所在的城市引入了新的区号 对于前缀小于 500 的电话号码 区号 111 保持不变 前缀为 500 及以上的号码将分配区号 222 客户表中电话列中的所有电话号
  • 在 SQL Server 中选择条件的值[重复]

    这个问题在这里已经有答案了 在查询选择中 我想显示字段是否满足条件的结果 想象一下我有一张名为stock 该表有一列告诉我库存中每种商品的数量 我想做的是这样的 SELECT stock name IF stock quantity lt
  • 如何将 T-SQL 中的结果连接到列中?

    我正在处理一个查询 它应该给我这样的结果 Name Surname Language Date James Hetfield en gb fr 2011 01 01 Lars Ulrich gb fr ca 2011 01 01 但我的选择
  • 导致聚集索引扫描的日期参数

    我有以下查询 DECLARE StartDate DATE 2017 09 22 DECLARE EndDate DATE 2017 09 23 SELECT a col1 a col2 b col1 b col2 b col3 a col
  • 动态SQL生成列名?

    我有一个查询 我正在尝试将行值转换为列名称 目前我正在使用SUM Case As ColumnName 声明 像这样 SELECT SKU1 SUM Case When Sku2 157 Then Quantity Else 0 End A
  • 如何确保使用 Microsoft Sync Framework 同步成功?

    我正在使用微软同步框架 https msdn microsoft com en us sync bb736753 aspx同步两个 Microsoft SQL Server 上的表 我创建了一个测试应用程序 它每秒在远程服务器上的表中生成一

随机推荐

  • mysql.service 丢失但显示在列表中 - 安装失败

    我使用的是 Ubuntu 17 04 长话短说 在与 MariaDB 进行了一些斗争之后 我遵循了一些关于如何完全地从我的家庭服务器中删除 MySQL 和 MariaDB 现在我无法重新安装mysql server 当我尝试时出现此错误 F
  • 非 ANSI 文件的 TStringList 行为

    在我的应用程序中 当我想要导入文件时 我使用 TStringList 但是 当有人从Excel导出数据时 文件编码是UCS 2 Little Endian TStringList无法读取数据 有什么方法可以验证这种情况 识别文本编码并向用户
  • Mod_wsgi工作进程分段错误(11)

    我的 django 应用程序有问题 该应用程序由 apache mod wsgi 托管 我在应用程序中添加了一些 matplotlib 代码 apache 工作进程现在崩溃了 我将这个问题简化为以下内容 没有任何 matplotlib 导入
  • 添加模型到集合后自动保存

    我有一个收藏myCollection我向其中添加模型如下 myCollection add title Romeo and Juliette author Shakespear 我现在可以将这个添加的模型保存到服务器吗 骨干Collecti
  • 找不到方法:'Void Google.Apis.Util.Store.FileDataStore..ctor(System.String)'

    我已经被困在这个问题上好几天了 我从 google api 示例中复制了确切的代码以将文件上传到 Google Drive 这是代码 UserCredential credential GoogleWebAuthorizationBroke
  • Spark失败:引起:org.apache.spark.shuffle.FetchFailedException:框架太大:5454002341

    我正在为确定父子项的表生成层次结构 以下是使用的配置 即使在收到有关太大框架的错误后也是如此 火花特性 conf spark yarn executor memoryOverhead 1024mb conf yarn nodemanager
  • 什么是 XPS 文件以及如何使用它

    我有一个简单的 C net Web 应用程序 我正在使用 XPS 文件 我使用了以下代码 private void button1 Click object sender EventArgs e try string xpsFile D C
  • C++ 多维数组运算符

    是否可以以某种方式重载多维数组的运算符 就像是 class A int operator const int x const int y 不 那是不可能的 不过 还有两种选择 你可以有operator 返回较小维度的数组 对于 3D 数组
  • Swift 中的懒惰是什么意思? [复制]

    这个问题在这里已经有答案了 我询问了有关堆栈溢出的多个问题 但没有得到可以定义什么是 LAZY 关键字以及为什么我们在 Swift 中使用它的答案 我对 Swift 很陌生 请解释一下 该词在两种情况下使用 惰性变量是一种存储的属性 只计算
  • action:@selector(showAlert:) 如何在这个showAlert方法中传递参数?

    我正在将自定义按钮添加到我的UITableViewCell 在该按钮的操作中我想打电话showAlert 函数并希望在方法中传递单元格标签 我如何在其中传递参数showAlert方法 action selector showAlert 如果
  • ASP.NET Core 6 中的非缓冲输出

    我正在尝试使用真正基本的 ASP NET Core 6 应用程序实现简单的流 非缓冲输出 下面的简单代码应该将 hello world 文本输出到客户端 然后关闭连接 甚至通过添加文档IHttpResponseBodyFeature选项 a
  • Google 地图动态语言更改

    我在我的一个项目中使用backbone js 并且使用Google 地图api 版本3 根据一些ajax 响应 我想动态更改Google 地图语言 有什么方法可以做到这一点 任何建议将不胜感激 提前致谢 考虑以下示例 其中我使用按钮 但您可
  • Java 代码中出现“没有为‘plsql’语言注册查询执行器工厂”异常

    我有一个简单的报告 显示数据库中的字段 我在 Jasper 中设置了一个数据适配器并放置了查询 我可以从 Jasper 成功预览报告 但是当涉及到 Java 时 它无法编译报告并显示以下异常 2014 年 6 月 18 日下午 3 17 4
  • 测试实体框架数据库连接

    我有一个通过实体框架连接到 MYSQL 数据库的应用程序 它工作 100 完美 但我想添加一小段代码 用于在应用程序启动时测试与数据库的连接 我的想法是简单地对数据库运行一个小命令并捕获任何异常 但是如果出现问题 例如 App Config
  • 如何停止或暂停 Pandora 和 Spotify

    我有一个应用程序 具有启动应用程序 Pandora 站或快捷方式的功能 一切都很好 后来我想停止我启动的应用程序 这适用于大多数事情 但 Pandora 和 Spotify 并不总是关闭 有时他们会这样做 但并非总是如此 这似乎与当前的 U
  • 詹金斯使用什么外壳?

    Jenkins调用时使用什么shellshell命令 我在 Linux 机器上运行 Jenkins 从 执行 shell 部分的帮助 问号图标 运行 shell 脚本 默认为 sh 但这是可配置的 建设该项目 如果您转到管理 Jenkins
  • 使用 system.out.printf 格式化 java 字符串

    我一直在寻找很多关于 java 中的 System out printf 格式化字符串输出的问题 但我似乎不明白如何使用它 我正在尝试打印看起来像这样的漂亮专栏 601 GoPro Hero5 Black 276 95 602 GoPro
  • 查询具有 xmlns 节点属性的 XML 数据类型

    我有以下 SQL 查询 DECLARE XMLDOC XML SET XMLDOC
  • 如何在 PyTorch 中的特定新维度中重复张量

    如果我有一个张量A有形状 M N 我想重复张量 K 次 以便结果B有形状 M K N 和每片B k 应该具有相同的数据A 这是没有 for 循环的最佳实践 K可能在其他维度 torch repeat interleave and tenso
  • 父 ID 不在列表中时递归 CTE

    我有以下嵌套集 结果就是这棵树 1 2 4 7 8 10 9 3 5 6 13 11 12 我有一份产品清单 选择 ID 名称 来自产品 与类别的多对多关系 所有类别都可以有促销活动 好吧 现在问题来了 假设我有一个类别 7 8 6 的 P