我有一个交易表:
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)
我想要的是每个人最近支付的日期和金额。付款由TransCode定义(请参阅下面的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
当我运行内部查询时,我得到了每个人所期望的,按日期汇总的金额列表。但是,外部查询由于某种原因为每个人返回多行。它应该只为每个人返回一行: - (
有人可以告诉我我做错了吗?
如果您有任何其他信息需要更好地了解问题,请与我们联系。
提前感谢您提供的任何帮助,
本
答案 0 :(得分:1)
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
这样的事情应该有效
答案 1 :(得分:1)
你可以尝试更高效的窗口函数 - 这会让你感到困惑。
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
答案 2 :(得分:0)
由于您按PersonId和TotalAmount进行分组,因此您获得了多行,并且有多个日期具有相同的TotalAmount。
只需将您拥有的整个SQL包装在另一个选择中以获取MAX(LastPaymentDate):
SELECT PersonID, LastPaymentDate, TotalAmount FROM (
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 InnerSelect
GROUP BY PersonID, TotalAmount
ORDER BY PersonID
)
GROUP BY PersonID, LastPaymentDate, TotalAmount
HAVING LastPaymentDate = MAX(LastPaymentDate)
答案 3 :(得分:0)
我相信这会很好用(但我没有测试过。)
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
如果您遇到速度问题,我建议您将转码选择项目放在表格中并加入其中,它会比使用IN语句更快。