Sql server 使用SQL Server,如何在对金额求和且金额之和大于0时获取最近日期?

Sql server 使用SQL Server,如何在对金额求和且金额之和大于0时获取最近日期?,sql-server,Sql Server,我有一个事务表: CREATE TABLE [dbo].[Trans]( [ID] [char](6) NOT NULL, [PersonID] [char](6) NULL, [TransCode] [char](2) NULL, [TransDesc] [char](45) NULL, [TransDate] [datetime] NULL, [TransAmount] [numeric](18, 2) NULL) 我想要的是每个人最近付款的日期和金额。付款由转码定义(见下面的WHERE条

我有一个事务表:

CREATE TABLE [dbo].[Trans](
[ID] [char](6) NOT NULL,
[PersonID] [char](6) NULL,
[TransCode] [char](2) NULL,
[TransDesc] [char](45) NULL,
[TransDate] [datetime] NULL,
[TransAmount] [numeric](18, 2) NULL)
我想要的是每个人最近付款的日期和金额。付款由转码定义(见下面的WHERE条款)

在任何一天都可能有多笔交易,因此我需要最近一天的交易总数。此外,还可能存在“冲销”交易,使最近一天的交易总额为0(零)——我不希望这些交易出现在结果中(因此下面的“HAVING(sum(TransAmount)>0”)

这是我最近的一次尝试,没有成功,但我不知道为什么

SELECT  PersonID, MAX(TransDate) AS LastPaymentDate, TotalAmount  
FROM    (SELECT   PersonID, TransDate, SUM(TransAmount) AS TotalAmount
         FROM     Trans
         WHERE    (TransCode IN ('11', '12', '13', '14', '18', '19', '61', '63', '68', '70', '71', '72', '73', '74', '75', '76', '78', '79', '80', '81', '94', 'P2'))
         GROUP BY PersonID, TransDate
         HAVING   (SUM(TransAmount) > 0)
         ORDER BY PersonID, TransDate) AS TotalAmount
GROUP BY PersonID, TotalAmount
ORDER BY PersonID
当我运行内部查询时,我得到了每个人的期望值,一个按日期汇总的金额列表。然而,出于某种原因,外部查询为每个人返回多行。每个人只能返回一行:-(

谁能告诉我我做错了什么

请让我知道,如果有任何额外的信息,你可能需要更好地了解这个问题

提前感谢您提供的任何帮助


Ben

由于按PersonId和TotalAmount进行分组,因此您将获得多行,并且有多个日期具有相同的TotalAmount

只需将您拥有的整个SQL包装到另一个select中即可获取最大值(LastPaymentDate):


像这样的东西应该可以用

我相信这会很好用(但我没有测试它)


如果您遇到速度问题,我建议您将trans-code select项放在一个表中,并在表中加入,这将比使用in语句更快。

您可以尝试使用更高效的窗口功能-这应该可以工作

select personid,trandate,SUM(transamount) as total 
from(
select personid,
CAST(transdate as DATE) as Trandate,transamount,
RANK() over(partition by personid order by
 CAST(transdate as DATE) desc) as rnk
 from trans
 ) as x
 where rnk=1
 group by PersonID,trandate

首先,将内部选择的名称更改为“TotalAmount”以外的名称,这有点混乱。通过删除内部选择的Order by并将transdate添加到第二个内部选择的group by,使其实际运行后,它起了作用。我必须尝试一下……看起来很有趣。我使用了您使用的一些东西,like“OVER”和“PARTITION BY”。LOL…应该是这样的:“我必须尝试一下……看起来很有趣。我从来没有用过你用过的一些东西,比如“OVER”和“PARTITION BY”“,这是一个很重要的词,应该错过;-)让我知道它是怎么回事——理论上你应该可以用它来摆脱子查询,但这是一天的结束。。。。
SELECT  LastDate.PersonID, LastDate.TransDate AS LastPaymentDate, TotalAmount.TotalAmount  
FROM    (SELECT   PersonID, Max(TransDate) as TransDate
         FROM     Trans
         WHERE    (TransCode IN ('11', '12', '13', '14', '18', '19', '61', '63', '68', '70', '71', '72', '73', '74', '75', '76', '78', '79', '80', '81', '94', 'P2'))
         GROUP BY PersonID
         HAVING   (SUM(TransAmount) > 0)
         ORDER BY PersonID, TransDate) AS LastDate
INNER JOIN (SELECT PersonID, Transdate, SUM(TransAMount) as TotalAmount 
         FROM     Trans
         WHERE    (TransCode IN ('11', '12', '13', '14', '18', '19', '61', '63', '68', '70', '71', '72', '73', '74', '75', '76', '78', '79', '80', '81', '94', 'P2'))
         GROUP BY PersonID
         HAVING   (SUM(TransAmount) > 0)
         ORDER BY PersonID, TransDate) AS TotalAmount 
ON TotalAmount.PersonID = LastDate.PersonID AND TotalAmount.TransDate = LastDate.TransDate
ORDER BY LastDate.PersonID
WITH PersonDateSum AS
(
  SELECT   PersonID, TransDate, SUM(TransAmount) AS TotalAmount
         FROM     Trans
         WHERE    (TransCode IN ('11', '12', '13', '14', '18', '19', '61', '63', '68', '70', '71', '72', '73', '74', '75', '76', '78', '79', '80', '81', '94', 'P2'))
         GROUP BY PersonID, TransDate
         HAVING   (SUM(TransAmount) > 0)
         ORDER BY PersonID, TransDate
) 
SELECT PersonID, LastPaymentDate, TotalAmount
FROM PersonDateSum
WHERE ROW_NUMBER() OVER  (PARTITION BY PersonID, LastPaymentDate ORDER BY PersonID, LastPaymentDate DESC) = 1
ORDER BY PersonID
select personid,trandate,SUM(transamount) as total 
from(
select personid,
CAST(transdate as DATE) as Trandate,transamount,
RANK() over(partition by personid order by
 CAST(transdate as DATE) desc) as rnk
 from trans
 ) as x
 where rnk=1
 group by PersonID,trandate