sql - T-SQL LAG 函数默认值

标签 sql tsql window-functions

为什么在连接表中没有记录且只引用连接表字段的情况下,LAG函数的默认参数仅适用于返回结果的第一列?

为了更好地解释这一点,我创建了以下场景。

架构

  CREATE TABLE Blogs(
    Id int IDENTITY(1,1) CONSTRAINT PK_Blogs_Id PRIMARY KEY,
    Title NVARCHAR(1000)
  )

  CREATE TABLE Comments(
    Id int IDENTITY(1,1) CONSTRAINT PK_Comments_Id PRIMARY KEY,
    BlogId INT NOT NULL,
    CommentText NVARCHAR(max)
  )

  INSERT INTO Blogs (Title) VALUES ('Blog 1')
  INSERT INTO Blogs (Title) VALUES ('Blog 2')
  INSERT INTO Blogs (Title) VALUES ('Blog 3')
  INSERT INTO Blogs (Title) VALUES ('Blog 4')
  INSERT INTO Blogs (Title) VALUES ('Blog 5')

  INSERT INTO Comments (BlogId, CommentText) VALUES (4,'Some text')
  INSERT INTO Comments (BlogId, CommentText) VALUES (4,'Some text 2')

查询

SELECT *, 
  LAG(CommentText,1,'No comment') OVER (Partition by Comments.BlogId ORDER BY Comments.Id Desc) LastComment
FROM Blogs LEFT JOIN Comments on Blogs.Id = Comments.BlogId;

在上面的查询中,它将返回第一行 LastComment 为“No comment”的结果,如果该行有其他评论,其余的将为空。

如果您在窗口函数(下面的查询)中引用 Blogs 的键,我知道它可以正常工作(所有为 null 的行在 LastComment 字段中返回“No comment”),但我试图理解为什么如果连接返回一个 null,为什么它不应用 LastComment LAG 函数中的默认参数。

SELECT *, 
  LAG(CommentText,1,'No comment') OVER (Partition by Blogs.Id ORDER BY Comments.Id Desc) LastComment
FROM Blogs LEFT JOIN Comments on Blogs.Id = Comments.BlogId;

这是场景 http://sqlfiddle.com/#!18/eb850/9 的 SQL fiddle

最佳答案

在 SQL Server 中,LAG() 函数用于根据排序列访问结果集中的前一行。它有一个可选的默认参数,指定在没有前一行时要返回的值。

如果您使用 LAG() 函数访问连接表中的列,并且连接表中没有与第一个表中的当前行匹配的记录,则默认参数将仅应用于第一个表的第一列返回的结果。这是因为 LAG() 函数旨在为结果集中的每一行返回一个值,如果连接表中没有匹配的行,则不可能为单个行返回多个值。

例如,考虑以下查询:

SELECT t1.id, t1.data, t2.data
FROM table1 t1
LEFT JOIN table2 t2
ON t1.id = t2.id

如果 table2 中没有与 table1 中的特定行匹配的行,则该行的 t2.data 列将为 NULL。如果您想使用 LAG() 函数访问 t2.data 的前一个值,您可以使用以下查询:

SELECT t1.id, t1.data, t2.data, LAG(t2.data) OVER (ORDER BY t1.id) AS prev_data
FROM table1 t1
LEFT JOIN table2 t2
ON t1.id = t2.id

在这种情况下,LAG() 函数将根据 OVER() 子句中指定的顺序为结果集中的每一行返回 t2.data 的前一个值。如果没有前面的行,将使用 LAG() 函数中指定的默认值。此默认值仅适用于 prev_data 列,因为它是唯一使用 LAG() 函数访问的列。结果集中的其他列(t1.id、t1.data 和 t2.data)不会受到默认值的影响。

关于sql - T-SQL LAG 函数默认值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55473884/

相关文章:

mysql - 在sql中显示超过3个月的记录

sql - 数据库中 ID 字段的 INT 与唯一标识符

SQL Server 2008 连接两个查询

sql - 在 Postgres 中添加多个列的累积总和

sql - 如何连接上个月缺少行的两个表?

postgresql - postgreSQL 中的移动窗口平均值

SQL查询分组参数最大值

sql - AWS RDS 为数据库创建用户

sql - 基本 SQL SUM 和 JOIN

c# - TSQL BULK INSERT 行错误导致 C# 异常