SQL查询中的帐户开立和结算余额中的结算结果不正确?

时间:2014-03-26 18:57:15

标签: c# mysql sql sql-server sql-server-2008

我发现每日账户开盘和收盘余额但是当同一日期有多个记录时,它会给我错误的结果。这是我的查询

    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)

查询结果

enter image description here

这是我的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

1 个答案:

答案 0 :(得分:1)

你有一些阴谋反对你的问题。首先,您在日期上summinggrouping,但您的时间戳保持不变。然后,您的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进行分组,否则您将为每位囚犯获得相同的结果。