SQL Query计算平均

时间:2017-12-05 11:59:14

标签: sql sql-server sql-server-2008

我阅读了几篇关于类似问题的帖子,似乎无法找到正确的解决方案。我已经尝试将计算添加到查询的几个部分,但没有成功。我确信我错过了一些简单的事情。

我在矿场工作,我被要求完成以下任务:

他们想知道哪些卡车在过去3天内比所有其他卡车平均有效载荷的平均有效载荷低5%以上。它还需要排除任何载荷小于10的卡车

共有3个表格:

  1. hist_loads(提供有效载荷和许多其他信息)

  2. hist_exproot(提供与日期相关的信息,需要这样做

  3. hist_eqmtlist(需要这个来确定具体的卡车型号,如 并非所有卡车车型都必须包括在内)

  4. 所有上述表格都由一个名为“shiftindex”的列连接在一起

    以下是我的查询:

        IF OBJECT_ID ('tempdb.dbo.#pave') IS NOT NULL DROP TABLE dbo.#pave;
    IF OBJECT_ID ('tempdb.dbo.#pfinal') IS NOT NULL DROP TABLE dbo.#pfinal;
    
    select  
        shiftdate
        ,truck
        ,AVG(measureton) as measureton
        ,COUNT(excav) as loads
    into #pfinal
    from hist_loads as hl
    inner join hist_exproot as he on 
    he.shiftindex = hl.shiftindex 
    inner join hist_eqmtlist as heq on
    heq.shiftindex = hl.shiftindex and 
    hl.truck = heq.eqmtid
    where hl.shiftindex between 
                                (select min(shiftindex) 
                                from hist_exproot 
                                where datepart(year,shiftdate) = datepart(year, getdate()-3)
                                and datepart(month,shiftdate) = datepart(month, getdate()-3)
                                and datepart(day,shiftdate) = datepart(day, getdate()-3))
            and 
                                (select max(shiftindex) 
                                from hist_exproot 
                                where datepart(year,shiftdate) = datepart(year, getdate()-1)
                                and datepart(month,shiftdate) = datepart(month, getdate()-1)
                                and datepart(day,shiftdate) = datepart(day, getdate()-1)) 
    
    and eqmttype in ('Euclid EH4500','Euclid EH4500-W','Euclid EH4500-HW')
    and expit like 1
    and measureton not like 0
    
    group by eqmttype, truck, shiftdate
    having COUNT(excav) > 10
    
    select  
        shiftdate
        ,AVG(measureton) as measureton
        ,COUNT(excav) as loads
    into #pave
    from hist_loads as hl
    inner join hist_exproot as he on 
    he.shiftindex = hl.shiftindex 
    inner join hist_eqmtlist as heq on
    heq.shiftindex = hl.shiftindex and 
    hl.truck = heq.eqmtid
    where hl.shiftindex between 
                                (select min(shiftindex) 
                                from hist_exproot 
                                where datepart(year,shiftdate) = datepart(year, getdate()-3)
                                and datepart(month,shiftdate) = datepart(month, getdate()-3)
                                and datepart(day,shiftdate) = datepart(day, getdate()-3))
            and 
                                (select max(shiftindex) 
                                from hist_exproot 
                                where datepart(year,shiftdate) = datepart(year, getdate()-1)
                                and datepart(month,shiftdate) = datepart(month, getdate()-1)
                                and datepart(day,shiftdate) = datepart(day, getdate()-1)) 
    
    and eqmttype in ('Euclid EH4500','Euclid EH4500-W','Euclid EH4500-HW')
    and measureton not like 0
    
    group by eqmttype, shiftdate
    having COUNT(excav) > 10
    
    select ave.shiftdate, ave.measureton, final.truck
    from #pave as ave
    left join #pfinal as final on 
    ave.shiftdate = final.shiftdate
    where final.measureton < ave.measureton
    order by truck
    

    我的结果:

    shiftdate           measureton         truck
    2017-12-03 00:00:00 230.444365964912    DT01
    2017-12-02 00:00:00 231.123014419048    DT04
    2017-12-02 00:00:00 231.123014419048    DT07
    2017-12-03 00:00:00 230.444365964912    DT07
    2017-12-04 00:00:00 226.141955641026    DT07
    2017-12-04 00:00:00 226.141955641026    DT10
    2017-12-02 00:00:00 231.123014419048    DT13
    2017-12-03 00:00:00 230.444365964912    DT14
    2017-12-02 00:00:00 231.123014419048    DT15
    2017-12-03 00:00:00 230.444365964912    DT17
    2017-12-04 00:00:00 226.141955641026    DT17
    2017-12-03 00:00:00 230.444365964912    DT20
    2017-12-04 00:00:00 226.141955641026    DT20
    2017-12-02 00:00:00 231.123014419048    DT22
    2017-12-04 00:00:00 226.141955641026    DT24
    2017-12-02 00:00:00 231.123014419048    DT25
    2017-12-02 00:00:00 231.123014419048    DT27
    2017-12-03 00:00:00 230.444365964912    DT27
    2017-12-04 00:00:00 226.141955641026    DT28
    2017-12-02 00:00:00 231.123014419048    DT30
    2017-12-02 00:00:00 231.123014419048    DT31
    2017-12-03 00:00:00 230.444365964912    DT31
    2017-12-04 00:00:00 226.141955641026    DT32
    

    但我只需要平均有效载荷以下5%以上的卡车。上述结果似乎是过去3天内所有卡车的平均有效载荷。而且在3个数字之间似乎也有一些重复。

    任何帮助都将不胜感激。

3 个答案:

答案 0 :(得分:0)

如果没有可测试且可验证的示例,很难回答,但我设法做到了:

 0 info it worked if it ends with ok
    1 verbose cli [ 'C:\\Program Files\\nodejs\\node.exe',
    1 verbose cli   'C:\\Program Files\\nodejs\\node_modules\\npm\\bin\\npm-cli.js',
    1 verbose cli   'run',
    1 verbose cli   'coverage' ]
    2 info using npm@5.3.0
    3 info using node@v6.4.0
    4 verbose run-script [ 'precoverage', 'coverage', 'postcoverage' ]
    5 info lifecycle gulp-karma@1.0.0~precoverage: gulp-karma@1.0.0
    6 info lifecycle gulp-karma@1.0.0~coverage: gulp-karma@1.0.0
    7 verbose lifecycle gulp-karma@1.0.0~coverage: unsafe-perm in lifecycle true
    8 verbose lifecycle gulp-karma@1.0.0~coverage:
    9 verbose lifecycle gulp-karma@1.0.0~coverage: CWD: D:\workspace\TestGroup\viewer
    10 silly lifecycle gulp-karma@1.0.0~coverage: Args: [ '/d /s /c',
    10 silly lifecycle   'concurrently "gulp common" "gulp feature" "gulp file" "gulp layout" "gulp widget_zero" "gulp widget_one" "gulp mobile_common" "gulp mobile_feature" "gulp mobile_file" "gulp mobile_layout" "gulp mobile_widget"' ]
    11 silly lifecycle gulp-karma@1.0.0~coverage: Returned: code: 1  signal: null
    12 info lifecycle gulp-karma@1.0.0~coverage: Failed to exec coverage script
    13 verbose stack Error: gulp-karma@1.0.0 coverage: `concurrently "gulp common" "gulp feature" "gulp file" "gulp layout" "gulp widget_zero" "gulp widget_one" "gulp mobile_common" "gulp mobile_feature" "gulp mobile_file" "gulp mobile_layout" "gulp mobile_widget"`
    13 verbose stack Exit status 1
    13 verbose stack     at EventEmitter.<anonymous> (C:\Program Files\nodejs\node_modules\npm\lib\utils\lifecycle.js:289:16)
    13 verbose stack     at emitTwo (events.js:125:13)
    13 verbose stack     at EventEmitter.emit (events.js:213:7)
    13 verbose stack     at ChildProcess.<anonymous> (C:\Program Files\nodejs\node_modules\npm\lib\utils\spawn.js:40:14)
    13 verbose stack     at emitTwo (events.js:125:13)
    13 verbose stack     at ChildProcess.emit (events.js:213:7)
    13 verbose stack     at maybeClose (internal/child_process.js:927:16)
    13 verbose stack     at Process.ChildProcess._handle.onexit (internal/child_process.js:211:5)
    14 verbose pkgid gulp-karma@1.0.0
    15 verbose cwd D:\workspace\TestGroup\viewer
    16 verbose Windows_NT 10.0.14393
    17 verbose argv "C:\\Program Files\\nodejs\\node.exe" "C:\\Program Files\\nodejs\\node_modules\\npm\\bin\\npm-cli.js" "run" "coverage"
    18 verbose node v6.4.0
    19 verbose npm  v5.3.0
    20 error code ELIFECYCLE
    21 error errno 1
    22 error gulp-karma@1.0.0 coverage: `concurrently "gulp common" "gulp feature" "gulp file

这是获得平均值并将其存储在where子句中使用的变量的简单案例。

答案 1 :(得分:0)

看起来你非常接近......没有你的实际数据就无法确认,但让我们看看这个简化的查询是否适合你......

第一个查询,我已经预先计算出只收集基于日期字段的数据,而不必单独分解年/月/日。

GetDate()本身将返回当前日期和时间。为了得到日期,我正在运行CONVERT(date,getdate()),所以2017-12-05 08:22:15 am被剥夺到2017-12-05。此外,通过做dateadd()-3天将把这个降低到2017-12-02。 where子句现在&gt; ='2017-12-02'并且比'2017-12-05'少,包括'2017-12-04 at 11:59:59 pm'获得整个12-04天覆盖了您要求的整个3天。

你最初的计数&gt; 10但据说要丢弃任何少于10次旅行的人,所以我改为&gt; = 10.你的其他标准保持原样。

因此,在对临时表的第一次查询结束时,仅为符合条件的卡车提供3天的活动,并获得每辆卡车的平均值。

SELECT
      shiftdate,
      truck,
      AVG(measureton) as measureton,
      COUNT(excav) as loads
   into 
      #pTruckAvgs
   from
      hist_loads as hl
         inner join hist_exproot as he 
            ON hl.shiftindex = he.shiftindex
         inner join hist_eqmtlist as heq 
            ON hl.shiftindex = heq.shiftindex 
            and hl.truck = heq.eqmtid
   where 
          hl.shiftindex >= DateAdd( day, -3, CONVERT(date, getdate()) )
      and hl.shiftindex < CONVERT(date, getdate())
      and eqmttype in ('Euclid EH4500','Euclid EH4500-W','Euclid EH4500-HW')
      and expit like 1
      and measureton not like 0
   group by 
      eqmttype, 
      truck, 
      shiftdate
   having 
      COUNT(excav) >= 10;

现在,您有一张所有卡车的临时表及其各自的平均值。您不需要根据日期再次重新查询,只需从此临时表中获取平均值(通过QualAvgs结果别名)。在这里,你寻找比平均值低5%,所以我采取平均值* .95并得到所有卡车平均值低于所有平均值的95%。完成后删除临时表。

select
      TA.*,
      QualAvgs.AllAvg
    from
       #pTruckAvgs TA,
       ( select AVG(measureton) as AllAvg
            from #pTruckAvgs ) QualAvgs
    where
       TA.measureTon < ( QualAvgs.AllAvg * .95);


drop table #pTruckAvgs;

现在最后的想法...对于每天的平均值可能需要稍微改变......例如,如果恶劣的天气或其他不可预见的限制使每辆卡车在一天内变慢,您可能需要

select
      TA.*,
      QualAvgs.AllAvg
    from
       #pTruckAvgs TA,
       ( select shiftdate,
                 AVG(measureton) as AllAvg
            from #pTruckAvgs 
            group by shiftdate ) QualAvgs
    where
           TA.measureTon < ( QualAvgs.AllAvg * .95)
       AND TA.ShiftDate = QualAvgs.ShiftDate;

答案 2 :(得分:0)

@DRapp。谢谢,这有点工作,有点调整。您的日期逻辑在SSMS中给了我一些错误。所以我用我的日期逻辑替换它:

Msg 206, Level 16, State 2, Line 1
Operand type clash: date is incompatible with int

我还在select语句中删除了shiftdate,因为我意识到不需要将它拆分成单独的日期。根据要求,我还将时间范围延长至7天。所以最终的工作查询如下:

IF OBJECT_ID ('tempdb.dbo.#pTruckAvgs') IS NOT NULL DROP TABLE dbo.#pTruckAvgs;

SELECT
      truck,
      AVG(measureton) as measureton,
      COUNT(excav) as loads
   into 
      #pTruckAvgs
   from
      hist_loads as hl
         inner join hist_exproot as he 
            ON hl.shiftindex = he.shiftindex
         inner join hist_eqmtlist as heq 
            ON hl.shiftindex = heq.shiftindex 
            and hl.truck = heq.eqmtid
   where 
          hl.shiftindex between 
                            (select min(shiftindex) 
                            from hist_exproot 
                            where datepart(year,shiftdate) = datepart(year, getdate()-7)
                            and datepart(month,shiftdate) = datepart(month, getdate()-7)
                            and datepart(day,shiftdate) = datepart(day, getdate()-7))
        and 
                            (select max(shiftindex) 
                            from hist_exproot 
                            where datepart(year,shiftdate) = datepart(year, getdate()-1)
                            and datepart(month,shiftdate) = datepart(month, getdate()-1)
                            and datepart(day,shiftdate) = datepart(day, getdate()-1)) 
      --and hl.shiftindex < CONVERT(date, getdate())
      and eqmttype in ('Euclid EH4500','Euclid EH4500-W','Euclid EH4500-HW')
      and expit like 1
      and measureton not like 0
      and measureton > 150
   group by 
      eqmttype, 
      truck
   having 
      COUNT(excav) >= 10;

select
      TA.*,
      QualAvgs.AllAvg
    from
       #pTruckAvgs TA,
       (select AVG(measureton) as AllAvg
            from #pTruckAvgs ) QualAvgs
    where
       TA.measureTon < ( QualAvgs.AllAvg * .95);

结果如下:

truck   measureton          loads   AllAvg
DT05    204.876060232558    43      224.850465129605

感谢大家的帮助,我们非常感谢。