在单个查询中按 Asc 和 Desc 排序
Order By Asc and Desc both in single query
我有一个查询可以从 table 检索最新数据,分页工作正常。
但是一旦数据比当前时间更早,它也应该出现在最新数据之后。
SELECT A.UserId,A.FirstName,A.LastName,A.PostDate
(SELECT ROW_NUMBER() OVER(ORDER BY CAST(M.PostDate AS DATETIMEOFFSET) DESC) AS 'RowNumber'
M.UserId,
M.FirstName,
M.LastName,
M.PostDate
FROM Messages AS M
Where M.PostDate >= GetDate()
) A
WHERE A.RowNumber BETWEEN @RowStart AND @RowEnd
ORDER BY CAST(A.PostDate AS DATETIMEOFFSET) DESC
我认为你应该删除下面这行
Where M.PostDate >= GetDate()
你不能在 Table 的同一列上做 Order By ASC
和 DESC
如果你这样做你会得到以下错误
Msg 169, Level 15, State 1, Line 1 A column has been specified more
than once in the order by list. Columns in the order by list must be
unique.
如果你想要它,你可以使用相同 Table 的 Join 并按相同的列排序,如
SELECT A.UserId,A.FirstName,A.LastName,A.PostDate
(SELECT ROW_NUMBER() OVER(ORDER BY CAST(M.PostDate AS DATETIMEOFFSET) DESC) AS 'RowNumber'
M.UserId,
M.FirstName,
M.LastName,
M.PostDate
FROM Messages AS M
Where M.PostDate >= GetDate()
) A
Inner Join Messages AS Msg on Msg.UserId=A.UserId
WHERE A.RowNumber BETWEEN @RowStart AND @RowEnd
ORDER BY CAST(A.PostDate AS DATETIMEOFFSET) DESC,
CAST(Msg.PostDate AS DATETIMEOFFSET) ASC
我不确定我是否得到了您正在寻找的东西,但这应该能让您接近。我创建了一个包含两个计算列的 CTE:
- BeforeAfter,确定日期是在传入日期之前还是之后
- AbsDiff,给出日期差异的绝对值。
然后,我只使用这两个字段进行排序:
DECLARE @current datetime = GETDATE()
;WITH cteMessages AS
(
SELECT UserId, FirstName, LastName, PostDate,
CASE WHEN PostDate < @current THEN 1 ELSE 0 END AS BeforeAfter,
ABS(DATEDIFF(SECOND, @current, PostDate)) AS AbsDiff
FROM Messages
)
SELECT * FROM cteMessages
ORDER BY BeforeAfter, AbsDiff
从这些结果中,您可以看到它们是如何首先按比传入日期新的邮件排序,然后按与旧邮件相反的顺序排序的。您可以将该顺序替换为 Row_Number 函数。
我有一个查询可以从 table 检索最新数据,分页工作正常。
但是一旦数据比当前时间更早,它也应该出现在最新数据之后。
SELECT A.UserId,A.FirstName,A.LastName,A.PostDate
(SELECT ROW_NUMBER() OVER(ORDER BY CAST(M.PostDate AS DATETIMEOFFSET) DESC) AS 'RowNumber'
M.UserId,
M.FirstName,
M.LastName,
M.PostDate
FROM Messages AS M
Where M.PostDate >= GetDate()
) A
WHERE A.RowNumber BETWEEN @RowStart AND @RowEnd
ORDER BY CAST(A.PostDate AS DATETIMEOFFSET) DESC
我认为你应该删除下面这行
Where M.PostDate >= GetDate()
你不能在 Table 的同一列上做 Order By ASC
和 DESC
如果你这样做你会得到以下错误
Msg 169, Level 15, State 1, Line 1 A column has been specified more than once in the order by list. Columns in the order by list must be unique.
如果你想要它,你可以使用相同 Table 的 Join 并按相同的列排序,如
SELECT A.UserId,A.FirstName,A.LastName,A.PostDate
(SELECT ROW_NUMBER() OVER(ORDER BY CAST(M.PostDate AS DATETIMEOFFSET) DESC) AS 'RowNumber'
M.UserId,
M.FirstName,
M.LastName,
M.PostDate
FROM Messages AS M
Where M.PostDate >= GetDate()
) A
Inner Join Messages AS Msg on Msg.UserId=A.UserId
WHERE A.RowNumber BETWEEN @RowStart AND @RowEnd
ORDER BY CAST(A.PostDate AS DATETIMEOFFSET) DESC,
CAST(Msg.PostDate AS DATETIMEOFFSET) ASC
我不确定我是否得到了您正在寻找的东西,但这应该能让您接近。我创建了一个包含两个计算列的 CTE:
- BeforeAfter,确定日期是在传入日期之前还是之后
- AbsDiff,给出日期差异的绝对值。
然后,我只使用这两个字段进行排序:
DECLARE @current datetime = GETDATE()
;WITH cteMessages AS
(
SELECT UserId, FirstName, LastName, PostDate,
CASE WHEN PostDate < @current THEN 1 ELSE 0 END AS BeforeAfter,
ABS(DATEDIFF(SECOND, @current, PostDate)) AS AbsDiff
FROM Messages
)
SELECT * FROM cteMessages
ORDER BY BeforeAfter, AbsDiff
从这些结果中,您可以看到它们是如何首先按比传入日期新的邮件排序,然后按与旧邮件相反的顺序排序的。您可以将该顺序替换为 Row_Number 函数。