Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/77.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
SELECT中聚合值的SQL总和_Sql_Sql Server - Fatal编程技术网

SELECT中聚合值的SQL总和

SELECT中聚合值的SQL总和,sql,sql-server,Sql,Sql Server,我有一个带有id和name字段的简单属性表。我还有一个propertyPrices表,其模式和数据如下所示 因此,它指定了给定日期范围的价格。价格值表示该期间内一天的成本 当给定开始和结束日期时,我希望能够根据每个日期范围之间的天数选择价格的总和 我尝试了以下几点: DECLARE @propertyID int = 1; DECLARE @startDate date = '2014/02/13'; DECLARE @endDate date = '2014/02/18'; /* get n

我有一个带有id和name字段的简单属性表。我还有一个propertyPrices表,其模式和数据如下所示

因此,它指定了给定日期范围的价格。价格值表示该期间内一天的成本

当给定开始和结束日期时,我希望能够根据每个日期范围之间的天数选择价格的总和

我尝试了以下几点:

DECLARE @propertyID int = 1;
DECLARE @startDate date = '2014/02/13';
DECLARE @endDate date = '2014/02/18';

/* get number of days between start and end date */
DECLARE @duration int = DATEDIFF(DAY, @startDate, @endDate)

/* select properties with holiday cost */
SELECT 
    property.name, SUM(dbo.propertyPrices.price) * @duration AS totalCost

FROM 
    dbo.property INNER JOIN dbo.propertyPrices ON dbo.property.id = dbo.propertyPrices.propertyID

WHERE 
    property.id = @propertyID

GROUP BY 
    dbo.property.name
返回2000作为总成本。这是5天,然后乘以400,这是所有价格的总和。我只想为范围内的每一天选择合适的价格。应该如此

100时2天+300时3天=1100

我不确定如何将单个日的值聚合起来。我的首要任务是表现

提前感谢您的帮助


尼克

我可以想象编写一个存储过程,或者另一种解决方案是建立一个只包含天数列表的辅助表

如果表calendardate中的所有日期都在受影响的范围内,则可以执行以下操作

SELECT 
    property.name, SUM(dbo.propertyPrices.price) AS totalCost

FROM 
    dbo.property
    INNER JOIN dbo.propertyPrices
        ON dbo.property.id = dbo.propertyPrices.propertyID
    JOIN calendar
        ON calendar.date between startDate and endDate

WHERE 
    property.id = @propertyID

GROUP BY 
    dbo.property.name

我相信您所需要做的就是在原始查询中添加一个case语句,定义您希望应用于日期边界和按开始日期和结束日期分组的条件,这将创建一个表,您可以将该表用作父查询,以按属性名称选择哪些分组

请参阅下面的代码,我使用了表varibales,因此可以轻松地对其进行测试,但您应该能够为自己的表名进行编辑,只需删除@

DECLARE @property AS Table(
    id INT 
,   name NVARCHAR(50)
)

INSERT INTO @property
SELECT 1, 'Property 1' UNION ALL
SELECT 2, 'Property 2'


DECLARE @propertyPrices AS Table(
    id INT 
,   propertyID INT
,   startDate datetime
,   endDate datetime
,   price float
)

INSERT INTO @propertyPrices
SELECT 1, 1, '2014-02-10', '2014-02-15', 100.00 UNION ALL
SELECT 2, 1, '2014-02-16', '2014-02-20', 300.00

DECLARE @propertyID int = 1;
DECLARE @startDate date = '2014/02/13';
DECLARE @endDate date = '2014/02/18';

/* get number of days between start and end date */
DECLARE @duration int = DATEDIFF(DAY, @startDate, @endDate)

/* select properties with holiday cost */
SELECT p.name, SUM(totalCost) FROM (
SELECT 
        p.name
    ,   CASE
            WHEN @startDate > pp.startDate AND @endDate > pp.endDate THEN 
                SUM(pp.price) * DATEDIFF(DAY, @startDate, @endDate)
            WHEN @endDate < pp.endDate THEN 
                SUM(pp.price) * DATEDIFF(DAY, pp.startDate, @endDate)
            ELSE 
                SUM(pp.price) * DATEDIFF(DAY, pp.startDate, pp.endDate)
        END
         AS totalCost

FROM 
    @property p INNER JOIN @propertyPrices pp ON p.id = pp.propertyID

WHERE 
    p.id = @propertyID

GROUP BY 
    p.name, pp.startDate, pp.endDate
) p GROUP BY p.name

我会用CTE来做。首先获得具有实际日期范围的价格,然后将价格乘以范围内的天数并求和

with cte as
(
  select propertyID, price,
  case when startDate < @startDate then @startDate else startDate end as startDate, 
  case when endDate > @endDate then @endDate else endDate end as endDate
  from propertyPrices
  where endDate >= @startDate
  and startDate <= @endDate
)
, cte2 as
(
  select propertyID, sum((datediff(day, startDate, endDate)+1) * price) as totalCost
  from cte
  group by propertyID
)
select name, totalCost
from cte2
inner join property on id = propertyID
where id = @propertyID

您可以在

上查看整个解决方案,我认为通过您传递的参数,它将是2天,而不是3天。您需要为每条记录设置@@startdate和@@enddate的重叠,我将使用案例构造来确定重叠的天数,重叠应乘以每条记录的价格。那个应该有一个总和,这个总和应该除以持续时间。谢谢AshReva,我更新了这个问题。保罗,你能提供一些演示代码吗?我想你的期望值是1200,因为3*10013-15feb+3*30016-18febawesome,谢谢-这就是我想要的那种简单性。我使用了一个表值函数来连接,它工作得很好!感谢您费尽心思创作了这把小提琴。我使用了另一种解决方案,因为我无法在我的上下文中使用CTE。