Sql 如何找到最近两个日期的两个值的差异
假设我有以下数据:Sql 如何找到最近两个日期的两个值的差异,sql,sql-server,Sql,Sql Server,假设我有以下数据: Client Date Money 31CDAAFE-93BA-4666-AE6D-2253059990BB 2011-08-31 200000000.00 31CDAAFE-93BA-4666-AE6D-2253059990BB 2011-07-31 198000000.00 31CDAAFE-93BA-46
Client Date Money
31CDAAFE-93BA-4666-AE6D-2253059990BB 2011-08-31 200000000.00
31CDAAFE-93BA-4666-AE6D-2253059990BB 2011-07-31 198000000.00
31CDAAFE-93BA-4666-AE6D-2253059990BB 2011-04-31 108000000.00
有没有一种简单的方法可以找出最新记录和第二次最新记录的金额(金钱)之间的差异
因此,对于该数据集,答案是:
31CDAAFE-93BA-4666-AE6D-2253059990BB 2011-08-31 2000000.00
我基本上需要返回第一条记录以及客户机和日期以及两条记录之间的差异。请注意,有多个客户、日期和资金,如果一个客户只有一个日期,我可以返回金额
我已经对数据进行了排名,但我一辈子都不知道如何在一行中结束结果……我是否遗漏了一些明显的东西
SELECT
Client,
Date,
Money,
ROW_NUMBER() OVER (PARTITION BY Client ORDER BY Date DESC) AS Sequence
FROM
MyTable
您可以尝试以下方法:
WITH CTE AS
(
SELECT
Client,
Date,
Money,
ROW_NUMBER() OVER (PARTITION BY Client ORDER BY Date DESC) AS Sequence
FROM MyTable
)
SELECT A.Client, A.[Money] - B.[Money] MoneyDifference
FROM (SELECT * FROM CTE WHERE Sequence = 1) A
INNER JOIN (SELECT * FROM CTE WHERE Sequence = 2) B
ON A.Client = B.Client
您可以尝试以下方法:
WITH CTE AS
(
SELECT
Client,
Date,
Money,
ROW_NUMBER() OVER (PARTITION BY Client ORDER BY Date DESC) AS Sequence
FROM MyTable
)
SELECT A.Client, A.[Money] - B.[Money] MoneyDifference
FROM (SELECT * FROM CTE WHERE Sequence = 1) A
INNER JOIN (SELECT * FROM CTE WHERE Sequence = 2) B
ON A.Client = B.Client
注:这包括没有“上一行”的情况
注意:这包括没有“上一行”的地方,您已经完成了大部分工作 剩下要做的就是将语句包装成一个语句,
JOIN
,并保留Sequence=1
中的所有行
请注意,只有一条记录的客户端将不会显示。我认为这是最合乎逻辑的做法。如果我的假设是错误的,您应该将内部联接
更改为左侧外部联接
配合使用
不带WITH的等价语句
正如您在注释中指出的,您应该仔细阅读使用WITH
语句,本质上就是示例中的WITH
语句
- 缩短了陈述
- 使它更具可读性
- 使它更易于维护
和
语句关联)
你已经完成了大部分工作 剩下要做的就是将语句包装成一个语句,
JOIN
,并保留Sequence=1
中的所有行
请注意,只有一条记录的客户端将不会显示。我认为这是最合乎逻辑的做法。如果我的假设是错误的,您应该将内部联接
更改为左侧外部联接
配合使用
不带WITH的等价语句
正如您在注释中指出的,您应该仔细阅读使用WITH
语句,本质上就是示例中的WITH
语句
- 缩短了陈述
- 使它更具可读性
- 使它更易于维护
和
语句关联)
我将其分解为两个嵌入式子查询:一个用于查找具有最长日期的行,另一个用于查找具有不等于第一个查询日期的最长日期的行,另一个用于在1=1时连接这些查询(因为您从每个查询中获得一行),然后得到整个查询中的差异。我会将其分解为两个嵌入式子查询:一个用于查找具有最长日期的行,另一个用于查找具有不等于第一个查询日期的最长日期的行,然后将这些查询按1=1进行联接(因为每个查询都有一行),然后在整个查询中得到差异。+1很好地使用了
序列+1
,而不是我的硬编码1和12@gbn-谢谢,但在这种情况下,硬编码就足够了,可能会提供更好的性能(如果优化器遇到了糟糕的一天:)+1很好地使用了序列+1
,而不是我的硬编码1和2@gbn-谢谢,但在这种情况下,硬编码就足够了,可能会提供更好的性能(如果优化器遇到了糟糕的一天:)
;WITH q AS (
SELECT
Client,
Date,
Money,
ROW_NUMBER() OVER (PARTITION BY Client ORDER BY Date DESC) AS Sequence
FROM
MyTable
)
SELECT q1.Client
, q1.Date
, q1.Money - q2.Money
FROM q q1
INNER JOIN q q2 ON q2.Client = q1.Client
AND q2.Sequence = q1.Sequence + 1
WHERE q1.Sequence = 1
SELECT q1.Client
, q1.Date
, q1.Money - q2.Money
FROM (
SELECT
Client,
Date,
Money,
ROW_NUMBER() OVER (PARTITION BY Client ORDER BY Date DESC) AS Sequence
FROM
MyTable
) q1
INNER JOIN (
SELECT
Client,
Date,
Money,
ROW_NUMBER() OVER (PARTITION BY Client ORDER BY Date DESC) AS Sequence
FROM
MyTable
) q2 ON q2.Client = q1.Client
AND q2.Sequence = q1.Sequence + 1
WHERE q1.Sequence = 1