如何从n个链接元组中选择最大值
我正在尝试从 sql server 数据库中的任何 n 个链接元组中选择最大 id - 我们正在为应用程序中的某些数据集编写升级脚本,并且需要知道基于数据的最高可用升级是什么目前版本是。例如,使用以下简化表“版本”:
oldVersionId newVersionId
1 2
2 3
3 4
10 11
我们知道我们是版本 1,并且希望获得可以升级到的最高版本;在这种情况下将返回 4,而不是 11。在任何给定时间,我们都可以有 0-n 个可用的可升级版本。我不是一个 sql 专家,只能考虑使用可变数量的链式选择进行查询:
select newVersion from versions where oldVersionId = (select newVersion from versions where oldVersionId = 1)
但它不是一个 n 编号的搜索,并且如果元素数量大于或小于给定的数量,则不会正确返回。 sql 是否能够执行这样的查询,我应该考虑哪些元素/关键字来编写查询?
解决方案:
你每天都会学到新东西 - 我需要这两个答案的混合。事实证明,sql 可以使用树状子/父链接来查询数据集,我在 OO 语言中更习惯这种链接。
在 sql server 中,您可以使用别名表设置递归树遍历调用。您需要一个锚点,然后是递归位。第一个调用是锚点,我可以使用表中的任何值或值列表等。第二个 select 调用只是说使用表的其余部分进行扫描。
语法如下:
--Create the new alias (s)
;with s (oldVersionId, newVersionId) as
(
--set up the anchor node,
select oldVersionId, newVersionId from @t
where oldVersionId = 1
-- join it to the rest of the table, denoting that we only want nodes
-- where the old version is represented as a new version later
union all
select t.oldVersionId, t.newVersionId from @t as t
inner join s on t.oldVersionId = s.newVersionId
)
--Return the max value from the nodes I collected
select max(s.newVersionId) from s
I'm trying to select the max id from any n number linked tuples in a sql server db - we are writing an upgrade script for some data sets within an app, and need to know what the highest upgrade available is based on what the data's version is currently. For example, using the following simplified table 'versions':
oldVersionId newVersionId
1 2
2 3
3 4
10 11
We know we are version 1, and want to get the highest version out there that we can upgrade to; which would return 4 in this case, and not 11. We can have 0-n number of upgradable versions available at any given time. I'm not an sql wiz, and could only think to query using a variable number of chained selects:
select newVersion from versions where oldVersionId = (select newVersion from versions where oldVersionId = 1)
But it not an n numbered search, and won't return correctly if the number of elements is greater or less then the given. Is sql capable of performing such a query, and what elements / keywords should I be looking at to write one?
Solution:
You learn something new every day - I needed a hybrid of the two answers. Turns out sql can query a dataset using the tree-like child/parent linking that I'm way more comfortable with in OO languages.
In sql server you can set up a recursive tree walking call using a aliased table. You need an anchor and then the recursive bit. The first call is the anchor, I can use any value in the table, or a list of values, etc. The second select call just says to use the rest of the table to scan against.
Here is the syntax:
--Create the new alias (s)
;with s (oldVersionId, newVersionId) as
(
--set up the anchor node,
select oldVersionId, newVersionId from @t
where oldVersionId = 1
-- join it to the rest of the table, denoting that we only want nodes
-- where the old version is represented as a new version later
union all
select t.oldVersionId, t.newVersionId from @t as t
inner join s on t.oldVersionId = s.newVersionId
)
--Return the max value from the nodes I collected
select max(s.newVersionId) from s
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
这是使用 CTE 的解决方案 - 当我们在 oldVersionId = newVersionId 上有下一个匹配时循环遍历数据:
这是没有 CTE 的解决方案 - 搜索 newVersionId 等于 1(第一个版本)的最后一条记录加上对此的增量更新的总和版本:
Here is the solution with CTE - loop thru data while we have next match on oldVersionId = newVersionId:
And here is solution without CTE - search for the last record which has newVersionId equals to 1 (1st version) plus the sum of imcremental updates to this version:
这个问题可以通过编写递归查询来遍历表中的递归层次结构来解决。
http:// www.mssqltips.com/sqlservertip/1520/recursive-queries-using-common-table-expressions-cte-in-sql-server/
http://msdn.microsoft.com/en-us/library/ms186243.aspx
This problem can be solved by writing recursive queries to traverse recursive hierarchies in a table.
http://www.mssqltips.com/sqlservertip/1520/recursive-queries-using-common-table-expressions-cte-in-sql-server/
http://msdn.microsoft.com/en-us/library/ms186243.aspx
您实际上需要识别链接列表中的最终节点 - 在我看来,您最好的选择是使用 CTE 的递归功能来获取“最大”版本,但我对 CTE 不够熟悉,无法获得它在职的。
下面得到了正确的答案,但只是因为我知道这个特定的虚拟表事先需要多少个链接;因此,并不理想。
You effectively need to identify the final node in a linked list--seems to me your best bet would be to use the recursive features of CTEs to get to your 'max' version, but I'm not familiar enough with CTEs to get it working.
The following gets to the right answer, but only because I know how many links this particular dummy table will require beforehand; thus, not ideal.
您的问题与 How让父级在 SQL SERVER 2005 中获得子级
我认为相同的 CTE 也适合您。
Your problem is pretty much same as How to get the parent given a child in SQL SERVER 2005
I think same CTE will work for you.