FORMAT 函数超出了 RANGE 窗口框架的 ORDER BY 列表支持的大小(错误 8279)
Posted
技术标签:
【中文标题】FORMAT 函数超出了 RANGE 窗口框架的 ORDER BY 列表支持的大小(错误 8279)【英文标题】:FORMAT function exceeding supported size of ORDER BY list of RANGE windows frame (error 8279) 【发布时间】:2018-02-22 07:40:50 【问题描述】:当谈到在 SQL Server 上显示我的日期的年月时,我喜欢使用这个解决方案:
format(year(<my_date>), '0000') + '-' + format(month(<my_date>), '00') as [year-month]
直到最近我都没有什么可抱怨的。
但是现在我需要使用该表达式来计算总计,事情变得越来越棘手。
数据如下所示:
ID | date
>
> 2514|2018-02-21
>
> 0249|2018-02-21
>
> 5122|2018-01-30
>
> 7410|2018-02-15
>
> 6638|2018-01-07
预期输出:
> running total of count(ID) | year-month
>
> 5|2018-02
>
> 2|2018-01
如您所见,我想获得整个集合的计数(ID)总数。
这是我的代码:
SELECT DISTINCT
count(id) over (partition by 1 order by format(year(<my_date>), '0000') + '-' + format(month(<my_date>), '00')),
format(year(<my_date>), '0000') + '-' + format(month(<my_date>), '00')
FROM my_table
ORDER BY format(year(<my_date>), '0000') + '-' + format(month(<my_date>), '00') desc
或者,简单地说:
SELECT DISTINCT
count(id) over (partition by 1 order by [year-month]),
[year-month]
FROM my_table
ORDER BY [year-month] desc
但它不起作用,因为我总是收到以下错误消息:
ORDER BY RANGE 窗口框架列表的总大小为 8000 字节。 支持的最大大小为 900 字节。
因此,我的问题是双重的:
-
为什么会收到此错误消息?
如何解决这个问题并获得我想要的结果?
编辑:我删除了我的代码的第二个版本,因为我意识到它是错误的。
【问题讨论】:
您确定需要运行总计吗?根据您的预期输出,您正在尝试group + count
如果只有两个期间(在我的示例中为 2018 年 1 月和 2018 年 2 月),我希望一行 count(ID's of first period) 和 count(ID's第一个时期的)+ 计数(第二个时期的 ID) 另一个。如果我最初介绍的问题不清楚,我深表歉意。
【参考方案1】:
您收到此消息是因为 SQL Server 无法“知道”FORMAT
调用的结果有多大,因此悲观地假设它可能高达 8000 字节。 1
您可以通过在结果中添加一些CAST
或CONVERT
调用来修复它。但我不会。
我会改为使用表达式
DATEADD(month,DATEDIFF(month,0,<my date>),0)
这会将每个日期值四舍五入到各自月份的第一天。是的,这些表达式仍然有一天的组成部分,但对于 grouping、ordering 和 partitioning 目的,只要它们'相等。
将 string 格式保留在您实际需要字符串的位置 - 在最终输出阶段,而不是在任何地方进行字符串操作。
1然后启动 900 字节限制,因为这是 SQL Server 支持的最大密钥大小,需要执行排序,它可能必须这样做才能满足这部分查询。
【讨论】:
好的,我明白了。我没有意识到 FORMAT 函数如此贪婪。这意味着我永远无法在我给出的示例中使用它(我的意思是使用分区),对吧? @Guillaume - 好吧,正如我在第二段中提到的那样,您可以在格式周围插入显式CAST
或 CONVERT
调用,为 SQL Server 提供显式大小信息,但总的来说我尝试如果有更自然的数据类型可用,则避免使用字符串。在这里,将数据保留为 datetime
意味着服务器的工作量要少得多。【参考方案2】:
你可以试试这个:
SELECT
COUNT(ID),
concat(yea, '-0', mon)
FROM (SELECT
company_id,
YEAR(date) AS yea,
MONTH(date) AS mon
FROM comdate) a
GROUP BY concat(yea, '-0', mon)
【讨论】:
以上是关于FORMAT 函数超出了 RANGE 窗口框架的 ORDER BY 列表支持的大小(错误 8279)的主要内容,如果未能解决你的问题,请参考以下文章
Excel excel函数参数中的range和reference有啥区别
[WebCoreSharedBufferData getBytes:range:]: 范围 0, 8 超出数据长度 0'