棘手的逻辑问题 - 如何为此查询创建基于集合的解决方案?
使用 SQL Server 2008 和 TSQL 的任何可用功能,我试图弄清楚如何解决以下问题是否存在不涉及临时表的基于集合的解决方案:
给定一组具有父子关系的节点,以及一组适用于每个的键值对,并且考虑到 节点层次结构较深层的值(对于给定的键值对)将覆盖具有相同键的值 是从祖先节点继承的,选择:
- 适用于给定节点的完整键值
- 对集 该节点的继承值集
模式如下:
create table Node
(
ID bigint identity primary key,
ParentID bigint null foreign key references Node(ID),
Name nvarchar(100)
);
create table KeyValuePair
(
ID bigint identity primary key,
KeyName nvarchar(100) not null,
Value nvarchar(1000) not null,
NodeID bigint not null foreign key references Node(ID),
unique (KeyName, NodeID)
);
结果集本质上包括列 KeyName< /code>、
值
、InheritedValue
。
我一直在尝试使用公用表表达式来做到这一点,但它的逻辑有点棘手。
Using SQL Server 2008 and any available features of TSQL, I am trying to work out how to if a set-based solution that does not involve a temp table exists for the following problem:
Given a set of nodes that have a parent-child relationship, and a set of key-value pairs that apply to each, and given that
the value (for a given key-value pair) at a deeper level of the node hierarchy will override a value with the same key that
is inherited from an ancestor node, select:
- the full set of key-value pairs that apply to a given node
- the set of inherited values for that node
The schema is as follows:
create table Node
(
ID bigint identity primary key,
ParentID bigint null foreign key references Node(ID),
Name nvarchar(100)
);
create table KeyValuePair
(
ID bigint identity primary key,
KeyName nvarchar(100) not null,
Value nvarchar(1000) not null,
NodeID bigint not null foreign key references Node(ID),
unique (KeyName, NodeID)
);
The result set would essentially include the columns KeyName
, Value
, InheritedValue
.
I've been trying to do this using a common table expression but the logic of it is a bit tricky.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
我根据问题设置了 Node 和 KeyValuePair 表,并填充了一些示例值,这样我的层次结构如下:
Root
|---A
| |---A1
| |---A2
|
|---B
|---B1
|---B2
我分配了两个属性,名为“Property 1”和“Property 2”,每个属性在根中定义,分别具有值“Root Prop 1”和“Root Prop 2” 。在 A 中,我用值“A Prop 1”覆盖“属性 1”,在 B 中,我用值“B Prop 2”覆盖“属性 2”。
调用节点 A1 的 Nathan 解决方案不会产生任何行!
Nathan 解决方案中的 where 子句应该是键和 v 之间连接的条件,导致修改后的过程如下所示(我还将 DataValue 重命名为 KeyValuePair 以与原始问题一致):
这产生了预期的正确结果:
I setup the Node and KeyValuePair tables as per the question, and populated with some sample values, such that my hierarchy was as follows:
Root
|---A
| |---A1
| |---A2
|
|---B
|---B1
|---B2
I assigned two properties, named "Property 1" and "Property 2", each defined in root with values "Root Prop 1" and "Root Prop 2" respectively. In A, I overrode "Property 1" with value "A Prop 1" and in B, I overrode "Property 2" with value "B Prop 2".
Calling Nathan's solution for node A1 yields no rows!
The where clause in Nathan's solution should be a condition of the join between keys and v, resulting in the revised procedure shown below (also I've renamed DataValue to KeyValuePair to be consistent with the original question):
This yielded the correct results as expected:
您应该考虑使用嵌套集模型来存储层次结构。这是描述它的链接:
http://mikehillyer.com/articles/managing-hierarchical-data-in -mysql/
它支持一种更加 SQL 友好的方法来检索有关分层信息的公共信息。
然后,您可以通过 Node 上的查询和 KeyValuePair 的单个连接来满足您的要求。
You should consider using the nested set model to store your hierarchy. Here is a link that describes it:
http://mikehillyer.com/articles/managing-hierarchical-data-in-mysql/
It supports a much more SQL friendly approach to retrieving common information about hierarchical information.
Your requirement here could then be satisfied with a query on Node and a single join to KeyValuePair.
好吧,我自己解决了。可能还有其他方法可以做到这一点,但这似乎效果很好:
Ok, I've solved it myself. There are probably other ways to do it, but this seems to work well enough:
这是物化路径大放异彩的案例之一。以下是我如何使用它解决类似问题:
将您的配置设置作为层次结构存储在数据库中。
This is one of those cases when materialized path shines. Here is how I solved a similar problem using it:
Store your configuration settings as a hierarchy in a database.