Sql server 2008 r2 我需要计算每辆车每月行驶的里程数

Sql server 2008 r2 我需要计算每辆车每月行驶的里程数,sql-server-2008-r2,Sql Server 2008 R2,我有一系列的车辆每天加油,输入总燃油和里程表读数。我需要计算每辆车每月行驶的里程数。 我的表格是燃油,车辆是公交车,日期是保养日期,里程表读数是里程,输入的燃油是数量 所以我会从每个月的第一个月开始计算里程数,然后从上个月的第一个月开始减去每辆车的里程数,在这个例子中是3237。更糟糕的是,如果车辆在第一次加油时没有加油,我会想要上个月最后一次加油时的里程数 service_date bus mileage quantity 7/1/2018 202 149654 34

我有一系列的车辆每天加油,输入总燃油和里程表读数。我需要计算每辆车每月行驶的里程数。 我的表格是燃油,车辆是公交车,日期是保养日期,里程表读数是里程,输入的燃油是数量

所以我会从每个月的第一个月开始计算里程数,然后从上个月的第一个月开始减去每辆车的里程数,在这个例子中是3237。更糟糕的是,如果车辆在第一次加油时没有加油,我会想要上个月最后一次加油时的里程数

service_date    bus mileage quantity    
7/1/2018    202 149654  34  
7/3/2018    202 150256  40.5    
7/4/2018    202 150562  42  
7/6/2018    202 150853  41  
7/7/2018    202 151191  37  
7/8/2018    202 151323  23.6    
7/15/2018   202 151502  39  
7/13/2018   202 151806  45  
8/1/2018    202 152891  37  3237

我不确定我是否理解您的所有具体要求,但以下是我如何编写查询来报告车队的里程数

首先,我将使用
groupby
MAX
获得每个月的最终里程数,如下所示:

SELECT bus_id
    , MAX(bus_mileage) AS 'ending_mileage'
    , DATEPART(YEAR, service_date) AS 'year'
    , DATEPART(MONTH, service_date) AS 'month'
    , MAX(service_date) AS 'last_service_date'
FROM @mileage
GROUP BY bus_id
    , DATEPART(YEAR, service_date)
    , DATEPART(MONTH, service_date)
然后我将使用它作为子查询来提取上个月的结束里程。这将为您提供本月的起始里程

SELECT  bus_id
        , ending_mileage
        , (
            SELECT MAX(bus_mileage)
            FROM @mileage m
            WHERE DATEPART(year, m.service_date) = DATEPART(YEAR, DATEADD(MONTH, -1, bus_mileage.last_service_date))
                AND DATEPART(MONTH, m.service_date) = DATEPART(MONTH, DATEADD(MONTH, -1, bus_mileage.last_service_date)) 
                AND m.bus_id = bus_mileage.bus_id
        ) AS 'starting_mileage'
        , mileage_year
        , mileage_month
FROM (
    SELECT bus_id
        , MAX(bus_mileage) AS 'ending_mileage'
        , DATEPART(YEAR, service_date) AS 'mileage_year'
        , DATEPART(MONTH, service_date) AS 'mileage_month'
        , MAX(service_date) AS 'last_service_date'
    FROM @mileage
    GROUP BY bus_id
        , DATEPART(YEAR, service_date)
        , DATEPART(MONTH, service_date)
) bus_mileage
然后,我将整个过程封装在一个外部查询中,该查询从结束里程中减去开始里程

SELECT  bus_id
      , ending_mileage
      , starting_mileage
      , ending_mileage - starting_mileage AS 'mileage_for_the_month'
      , mileage_year
      , mileage_month
FROM (
    SELECT  bus_id
          , ending_mileage
          , (
                SELECT MAX(bus_mileage)
                FROM @mileage m
                WHERE DATEPART(year, m.service_date) = DATEPART(YEAR, DATEADD(MONTH, -1, bus_mileage.last_service_date))
                    AND DATEPART(MONTH, m.service_date) = DATEPART(MONTH, DATEADD(MONTH, -1, bus_mileage.last_service_date)) 
                    AND m.bus_id = bus_mileage.bus_id
          ) AS 'starting_mileage'
          , mileage_year
          , mileage_month
    FROM (
        SELECT bus_id
            , MAX(bus_mileage) AS 'ending_mileage'
            , DATEPART(YEAR, service_date) AS 'mileage_year'
            , DATEPART(MONTH, service_date) AS 'mileage_month'
            , MAX(service_date) AS 'last_service_date'
        FROM @mileage
        GROUP BY bus_id
            , DATEPART(YEAR, service_date)
            , DATEPART(MONTH, service_date)
    ) bus_mileage
) monthly_mileage
下面是演示数据的全部内容,您可以看到它们是如何协同工作的

DECLARE @mileage TABLE(
    service_date DATE NOT NULL
  , bus_id  INT NOT NULL
  , bus_mileage INT NOT NULL
)
INSERT INTO @mileage (service_date, bus_id, bus_mileage)
VALUES ('7/1/2018', 202, 149654)
    , ('7/15/2018', 202, 151502)
    , ('8/1/2018', 202, 152891)
    , ('8/15/2018', 202, 153502)
    , ('9/3/2018', 202, 154891)
    , ('10/15/2018', 202, 155502)
    , ('11/3/2018', 202, 157891)
    , ('7/5/2018', 302, 155502)
    , ('8/3/2018', 302, 157691)

SELECT  bus_id
      , ending_mileage
      , starting_mileage
      , ending_mileage - starting_mileage AS 'mileage_for_the_month'
      , mileage_year
      , mileage_month
FROM (
    SELECT  bus_id
          , ending_mileage
          , (
                SELECT MAX(bus_mileage)
                FROM @mileage m
                WHERE DATEPART(year, m.service_date) = DATEPART(YEAR, DATEADD(MONTH, -1, bus_mileage.last_service_date))
                    AND DATEPART(MONTH, m.service_date) = DATEPART(MONTH, DATEADD(MONTH, -1, bus_mileage.last_service_date)) 
                    AND m.bus_id = bus_mileage.bus_id
          ) AS 'starting_mileage'
          , mileage_year
          , mileage_month
    FROM (
        SELECT bus_id
            , MAX(bus_mileage) AS 'ending_mileage'
            , DATEPART(YEAR, service_date) AS 'mileage_year'
            , DATEPART(MONTH, service_date) AS 'mileage_month'
            , MAX(service_date) AS 'last_service_date'
        FROM @mileage
        GROUP BY bus_id
            , DATEPART(YEAR, service_date)
            , DATEPART(MONTH, service_date)
    ) bus_mileage
) monthly_mileage

不确定这是否完全符合您的要求,但这是我根据您提供的信息报告里程数的方式。

您说如果没有一个月的第一天的记录,您需要上个月最后一天的燃油。你也想要同一张唱片的milage吗?我想你应该是始终如一的。预期的结果在这里会有所帮助。最后一排的3237是什么?在这种情况下,我认为3237是预期的结果-8月1日的里程数-7月1日的里程数。是的,3237是7月的里程数,即8月1日-7月1日。是的,这确实非常符合要求。这很有效,谢谢