我发现每日账户开盘和收盘余额但是当同一日期有多个记录时,它会给我错误的结果。这是我的查询
SELECT cast(TransDate as date)
, SUM ([Total deposits]) As 'Total deposits'
, SUM ([Total withdrawals]) As 'Total withdrawals'
, SUM (ClosingBalance) AS ClosingBalance
FROM (
SELECT TransDate
, ISNULL (SUM (Ledger.Cr), 0) AS 'Total deposits'
, ISNULL (SUM (Ledger.Dr), 0) AS 'Total withdrawals'
, 0 AS ClosingBalance
FROM Ledger where Ledger.TransDate between '2014-02-14' and '2014-02-20'
GROUP BY Ledger.TransDate
UNION ALL
SELECT TransDate
, 0 AS 'Total deposits'
, 0 AS 'Total withdrawals'
, ISNULL ((SELECT SUM (MT2.Cr) FROM Ledger MT2 WHERE MT2.TransDate <= MT.TransDate), 0)
- ISNULL ((SELECT SUM (MT2.Dr) FROM Ledger MT2 WHERE cast(MT2.TransDate as date ) <= MT.TransDate), 0)
FROM Ledger MT where TransDate between '2014-02-14' and '2014-02-20'
GROUP BY Transdate
) AS X
GROUP BY cast(TRANSDATE as date)
查询结果
这是我的db文件脚本
USE [MDS]
GO
/****** Object: Table [dbo].[Ledger] Script Date: 03/26/2014 23:42:04 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
SET ANSI_PADDING ON
GO
CREATE TABLE [dbo].[Ledger](
[id] [int] IDENTITY(1,1) NOT NULL,
[PrisonerID] [int] NULL,
[TransDate] [datetime] NULL,
[Dr] [money] NULL,
[Cr] [money] NULL,
[Partical] [varchar](50) NULL,
CONSTRAINT [PK_Ledger] PRIMARY KEY CLUSTERED
(
[id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
SET ANSI_PADDING OFF
GO
SET IDENTITY_INSERT [dbo].[Ledger] ON
INSERT [dbo].[Ledger] ([id], [PrisonerID], [TransDate], [Dr], [Cr], [Partical]) VALUES (1, 5, CAST(0x0000A2D200D9255B AS DateTime), 0.0000, 500.0000, N'payment recived')
INSERT [dbo].[Ledger] ([id], [PrisonerID], [TransDate], [Dr], [Cr], [Partical]) VALUES (2, 5, CAST(0x0000A2D300D9255B AS DateTime), 0.0000, 200.0000, N'withdraw')
INSERT [dbo].[Ledger] ([id], [PrisonerID], [TransDate], [Dr], [Cr], [Partical]) VALUES (3, 5, CAST(0x0000A2D400DBE47B AS DateTime), 20.0000, 0.0000, N'withdraw')
INSERT [dbo].[Ledger] ([id], [PrisonerID], [TransDate], [Dr], [Cr], [Partical]) VALUES (4, 5, CAST(0x0000A2D200000000 AS DateTime), 10.0000, 0.0000, N'withdraw')
INSERT [dbo].[Ledger] ([id], [PrisonerID], [TransDate], [Dr], [Cr], [Partical]) VALUES (5, 5, CAST(0x0000A2D700D9255B AS DateTime), 0.0000, 200.0000, N'payment revived')
INSERT [dbo].[Ledger] ([id], [PrisonerID], [TransDate], [Dr], [Cr], [Partical]) VALUES (6, 5, CAST(0x0000A2D20083D600 AS DateTime), 10.0000, 0.0000, N'withdraw')
SET IDENTITY_INSERT [dbo].[Ledger] OFF
/****** Object: Default [DF_Ledger_Dr] Script Date: 03/26/2014 23:42:04 ******/
ALTER TABLE [dbo].[Ledger] ADD CONSTRAINT [DF_Ledger_Dr] DEFAULT ((0.0000)) FOR [Dr]
GO
/****** Object: Default [DF_Ledger_Cr] Script Date: 03/26/2014 23:42:04 ******/
ALTER TABLE [dbo].[Ledger] ADD CONSTRAINT [DF_Ledger_Cr] DEFAULT ((0.0000)) FOR [Cr]
GO
答案 0 :(得分:1)
你有一些阴谋反对你的问题。首先,您在日期上summing
和grouping
,但您的时间戳保持不变。然后,您的UNION ALL
会导致这些内容在您的计算中重复。如果您在同一日期有其他存款,您会看到这些数字也会膨胀。
您还可以将求和查询合并到一个SELECT
和一些相关子查询中,如下所示:
SELECT dateadd(dd, datediff(dd, 0, a.TransDate), 0)
, ISNULL (SUM (a.Cr), 0) AS 'Total deposits'
, ISNULL (SUM (a.Dr), 0) AS 'Total withdrawals'
, ISNULL((SELECT SUM(Cr) from Ledger where dateadd(dd, datediff(dd, 0, TransDate), 0) <= dateadd(dd, datediff(dd, 0, a.TransDate), 0)), 0)
- ISNULL((SELECT SUM(Dr) from Ledger where dateadd(dd, datediff(dd, 0, TransDate), 0) <= dateadd(dd, datediff(dd, 0, a.TransDate), 0)), 0) as 'Closing Balance'
FROM Ledger a
where a.TransDate between '2014-02-14' and '2014-02-20'
GROUP BY dateadd(dd, datediff(dd, 0, a.TransDate), 0)
这是一个SQL Fiddle来演示。
此外,您可能还希望对PrisonerID
进行分组,否则您将为每位囚犯获得相同的结果。