sql server 导致 - 日期问题

标签 sql sql-server date lead

我对 sql server 2012 中新的领先 olap 函数有疑问。

CREATE TABLE Atext (id int, bez varchar(10), von date); 

GO

INSERT INTO Atext VALUES (1, 't1', '2001-01-01'), (1, 't2', '2012-01-01'), (2, 'a1', '2020-01-01'), (2,'a1' , '2030-01-01'), (2, 'b', '2040-05-01'), (2, 'a3', '2989-05-01'); 
GO

SELECT 
        id, 
        bez, 
        von,
        lead(von,1,0) over (partition by id ORDER BY von) -1 as bis
FROM 
        Atext
order by 
        id, 
        Von

选择查询抛出错误:

Msg 206, Level 16, State 2, Line 1 
Operand type clash: int is incompatible with date

为什么数据类型日期时间有限制?

我知道一个解决方法,但它不是很好:

SELECT
    id,
    bez,
    CAST(vonChar AS DATE) AS Von,
    CASE
        WHEN bisChar <> '0'
        THEN (DATEADD(DAY,-1,(CAST((
                    CASE
                        WHEN bisChar <> '0'
                        THEN vonChar
                        ELSE NULL
                    END)AS DATE)) ))
        ELSE NULL /*'9999-12-31'*/
    END AS Bis
FROM
    (
        SELECT
            id,
            bez,
            vonChar ,
            lead(vonChar,1,0) over (partition BY id ORDER BY vonChar) AS bisChar
        FROM
            (
                SELECT
                    id,
                    bez,
                    CAST(von AS VARCHAR(10)) vonChar
                FROM
                    Atext) tab ) tab2
ORDER BY
    id,
    Von

微软 SQL Server 2012 (SP1) - 11.0.3128.0 (X64)

最佳答案

使用日期(或可以隐式转换为日期的内容)作为引导函数的默认值,DATEADD 函数将是一个更简单的解决方法:

SELECT 
        id, 
        bez, 
        von,
        DATEADD(DAY, -1, LEAD(von, 1, '19000101') 
                        OVER (PARTITION BY id ORDER BY von)) AS bis
FROM Atext
ORDER BY id, Von;

或者只是不理会默认值。这不是必需的:

SELECT 
        id, 
        bez, 
        von,
        DATEADD(DAY, -1, LEAD(von, 1) 
                        OVER (PARTITION BY id ORDER BY von)) AS bis
FROM Atext
ORDER BY id, Von;

问题是您无法将 INT 转换为 DATE。在 SQL Server 的表达式中,表达式的所有部分都必须具有相同的数据类型,因此,如果您这样做:

SELECT TOP 1 GETDATE() + number
FROM master..spt_values
WHERE type = 'p'

在幕后,SQL Server 需要决定是将 GETDATE() 转换为整数,以便表达式的所有部分都是整数,还是将 1 转换为日期时间,以便 所有部分都是日期时间。 SQL Server 的 Data Type Precedence规定DATETIME比INT具有更高的优先级,因此SQL Server将1转换为日期时间,这可以在执行计划中看到:

<ScalarOperator ScalarString="getdate()+[Expr1005]">
....
<ColumnReference Column="Expr1005" />
<ScalarOperator ScalarString="CONVERT_IMPLICIT(datetime,[master].[dbo].[spt_values].[number],0)">

这表明 INT 列 master..spt_values.number 在添加到 getdate() 之前已隐式转换为日期时间

无论出于何种原因(不久前我进行了广泛的研究,没有找到任何可以解释原因的方法),没有从 int 到 date 的隐式或显式转换,您必须使用日期函数。

关于sql server 导致 - 日期问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23888823/

相关文章:

sql-server - XQuery - 迭代每个属性

Javascript Date.toString() 格式化?

java - 如何设置 swagger 文档以使用 dd/MM/yyyy 格式?

java - 如何搜索电影并更喜欢标题中包含搜索词的结果而不是描述中包含搜索词的结果

sql - IntelliJ IDEA 13 SQL 语句高亮

sql - 数据库处于恢复状态

linux - 如何在 shell 脚本中将时间戳转换为小时/分钟/秒?

sql - Postgresql 选择创建日期相差 2 小时的两行

SQL Server : OPENXML vs SELECT. .FROM 在处理 XML 时?

sql - Soundex 函数在 SQL Server 中如何工作?