C# 从价格周期表中获取金额

C# 从价格周期表中获取金额,c#,sql,winforms,ms-access,C#,Sql,Winforms,Ms Access,我有一个表价期tblPricePeriod,在这个表价期内,我有一个特定公寓在两个日期之间要收取的金额 我还使用ApartmentId为价格期设置了StartDate和EndDate列 以下是我的表格结构: 现在我想计算预订天数的总金额 例如,如果某人在2月4日至7日期间停留,则他必须按照以下计划付款: 4- 10 5- 10 6- 10 7 - nothing as this is checkout date --------------------

我有一个表价期tblPricePeriod,在这个表价期内,我有一个特定公寓在两个日期之间要收取的金额

我还使用ApartmentId为价格期设置了StartDate和EndDate列

以下是我的表格结构:

现在我想计算预订天数的总金额

例如,如果某人在2月4日至7日期间停留,则他必须按照以下计划付款:

4-     10
5-     10
6-     10  
7    -     nothing as this is checkout date 
-----------------------------------------------------
totamt--- 30$
我有startdate、enddate和apartmentid作为参数,我使用的是ms access数据库

现在,我使用c代码通过以下代码来遍历它,但没有成功

我一个接一个地获取所有日期的金额,并将其添加到一个全局变量中

代码如下:


下面是Sql中SUM函数的一个示例:

SELECT SUM(salary) as "Total Salary"
FROM employees
WHERE salary > 25000;
//编辑:

您可以直接选择金额的总和,而不是在日期时间上循环:

DateTime dtStartDate = Convert.ToDateTime(StartDate);
DateTime dtEndDate = Convert.ToDateTime(EndDate); // maybe -1 day 

string priceCalc = "select SUM( Amount ) from tblPricePeriod where ApartmentId=" + ApartmenId + " and cdate(StartDate) <= '" + dtStartDate.ToShortDateString( ) + "' and cDate(EndDate) >= '" + dtEndDate.ToShortDateString( ) + "'";

您可以采用完全SQL的方法:

SELECT  SUM(TotalAmount) AS Amount
FROM    (   SELECT  Amount * (1 + DATEDIFF('d', @StartDate, EndDate))  AS TotalAmount,  
                    (1 + DATEDIFF('d', @StartDate, EndDate)) AS Days, 
                    Amount AS DailyRate
            FROM    tblPricePeriod
            WHERE   @StartDate >= StartDate
            AND     @StartDate <= EndDate
            AND     @EndDate > EndDate
            AND     ApartmentID = @ApartmentID
            UNION ALL
            SELECT  Amount * (DATEDIFF('d', @StartDate, @EndDate)),  DATEDIFF('d', @StartDate, @EndDate), Amount
            FROM    tblPricePeriod
            WHERE   @StartDate >= StartDate
            AND     @StartDate <= EndDate
            AND     @EndDate >= StartDate
            AND     @EndDate <= EndDate
            AND     ApartmentID = @ApartmentID
            UNION ALL
            SELECT  Amount * (1 + DATEDIFF('d', StartDate, EndDate)),  (1 + DATEDIFF('d', StartDate, EndDate)) , Amount
            FROM    tblPricePeriod
            WHERE   @StartDate < StartDate
            AND     @EndDate > EndDate
            AND     ApartmentID = @ApartmentID
            UNION ALL
            SELECT  Amount * (DATEDIFF('d', StartDate, @EndDate)),  DATEDIFF('d', StartDate, @EndDate) , Amount
            FROM    tblPricePeriod
            WHERE   @StartDate < StartDate
            AND     @EndDate <= EndDate
            AND     @EndDate > StartDate
            AND     ApartmentID = @ApartmentID
        ) AS Data
由于Access不允许注释,我无法对查询进行注释。子查询有4个部分,顶部部分用于表示访问期间价格期结束日期,第二部分用于表示访问完全在一个价格期内,第三部分用于表示访问跨越整个价格期,第四部分用于表示访问期间价格期开始。希望这是清楚的

然后,您只需将参数@ApartmentID、@StartDate和@EndDate添加到ExecuteDataset方法中,这是一种比串接字符串更好的方法

SELECT
  SUM(( 
    IIF(EndDate < @EndDate, EndDate, IIF(@EndDate < StartDate, StartDate, @EndDate)) -
    IIF(StartDate > @StartDate, StartDate, IIF(@StartDate > EndDate, EndDate, @StartDate))
  ) * Amount)
FROM tblPricePeriod 
这采用了与GarethD相同的方法。它当然更短,但你可以争论哪一个更清楚地显示了意图。我无法测试这个,因为我没有访问权限,但我相信它有IIF声明。@EndDate参数必须是您的结束日期-1。因此,在您的示例中,我将通过@End Date=2月6日


IIF报表基本上计算每个期间需要计算的天数。

我不明白问题出在哪里?您得到的是错误还是错误的总和?此外,如果您不希望客户支付结帐日期的费用,则应在结帐日期使用>而不是>=模拟错误没有来自查询的数据,并且这些“StartDate”和“EndDate”列中没有数据,它们是否有“date”类型?Access不需要日期分隔符吗?能否尝试查找问题?priceCalc、dsPriceCalc或amount是否包含任何数据?是的,当我尝试快速手表时,它们有数据debugger@Viper如果有多条记录的startDate/EndDate是正确的,那么它将获取所有记录。这也是我的第一个想法,但出于某种原因,Access返回此表达式键入不正确,或太复杂而无法计算。例如,数值表达式可能包含太多复杂元素。请尝试通过将表达式的某些部分指定给变量来简化表达式.但是如果你用2012年2月27日的实际日期替换@StartDate,它运行得很好。我无法理解这一点,所以选择了工会方法,因为我能够让它工作。
SELECT
  SUM(( 
    IIF(EndDate < @EndDate, EndDate, IIF(@EndDate < StartDate, StartDate, @EndDate)) -
    IIF(StartDate > @StartDate, StartDate, IIF(@StartDate > EndDate, EndDate, @StartDate))
  ) * Amount)
FROM tblPricePeriod