混合变量分配和数据检索 - MySQL vs MS SQL Server
Posted
技术标签:
【中文标题】混合变量分配和数据检索 - MySQL vs MS SQL Server【英文标题】:Mixing variable assigment and data retrieval - MySQL vs MS SQL Server 【发布时间】:2019-11-01 19:10:14 【问题描述】:我正在尝试使用多年未使用的 sql 查询来刷新我的技能。
在做一些练习时,我遇到了一个在 mysql 中很容易解决但在 sql server 中更复杂的问题。我想知道是否有更简单的方法。
为了问题,我会过度简化问题(以避免复杂的代码)
所以,我有一个数字序列。在这个序列中,我想识别和编号数字 = 10 时,一个新的子序列开始由 seqno 计数器识别。下面是mysql查询+结果??????
create table myt1(mynum int);
insert into myt1 values (13), (5), (8), (15), (2), (5), (18), (3), (6), (9), (8), (12);
set @seqno = 0;
select mynum, @seqno := case when mynum < 10 then @seqno else @seqno+1 end as seqno
from myt1
现在使用 SQL 服务器,事情变得更加复杂,因为不允许在同一个 SELECT 语句中同时进行数据检索和变量赋值。我获得相同结果的解决方法是将表复制到带有附加列的临时表中,然后使用以下代码更新表/列????
create table myt1(mynum int);
insert into myt1 values (13), (5), (8), (15), (2), (5), (18), (3), (6), (9), (8), (12);
select *, 1 as seqno
into #tempt1
from myt1
declare @seqno int;
set @seqno = 0;
update #tempt1
set
seqno = @seqno,
@seqno = case when mynum < 10 then @seqno else @seqno+1 end
select * from #tempt1
谁能告诉我是否有更简单的方法可以在 mssql 中编写此查询,以及为什么在 mysql 中没有找到限制?
谢谢!
【问题讨论】:
因此,在 mysql 中,有人认为这样的东西很有用并且已经实现,今天使用 mysql 8,您将切换到窗口函数。 MSQL也有这样的窗口函数见docs.microsoft.com/de-de/sql/t-sql/functions/… 【参考方案1】:您似乎想要超过 10 的值的累积计数:
select mynum,
sum(case when mynum >= 10 then 1 else 0 end) over (order by id) as seqno
from myt1;
Here 是一个 dbfiddle。
请注意,SQL 表代表 无序 集。您的查询假定表的顺序——这在一般 SQL 或任一数据库中均无效。您的查询确实似乎在 MySQL 中有效,但不能保证。
我添加了一个id
列来捕获排序,因此查询将起作用。
顺便说一句,这也是 MySQL 8+ 中的首选方法;不推荐使用变量。
【讨论】:
自 2012 年以来,Sql Server 已经支持这种 正确 和 标准 方法,而 MySql 仅具有窗口函数,在此之前有 根本没有办法这样做可以保证正确的排序:再一次,它似乎只在大部分时间工作,因为数据存储在磁盘或内存中的方式发生了意外,以及你在哪里查询突然命中不同的索引可能会诱使引擎使用旧方法完全破坏 MySqls 结果。 @JoelCoehoorn 。 . .实际上,这个特殊的问题可以通过关联子查询来解决,所以在 MySQL 中一直有解决方案。 谢谢 Gordon,我不认为 sum+over 组合,对不起,正如我在 Q 中所说,我想过度简化,所以删除了非常重要的 id 排序列,这是我的错误。但我很快在dbfiddle.uk/… 的原始查询中添加了“id”,这个查询现在有什么问题吗?我特别问@JoelCoehoorn,他似乎说我的原始查询本质上是错误的,因为使用变量而不是窗口函数。以上是关于混合变量分配和数据检索 - MySQL vs MS SQL Server的主要内容,如果未能解决你的问题,请参考以下文章
从 MySQL 数据库获取数据后,从第 n 行获取列数据并分配给变量
mysql vs ms-access DB上的sql查询左连接