SQL计算两行中的列

时间:2012-12-17 22:04:04

标签: sql multiple-columns calculated-columns

我正在寻找基于另外两列的计算列,但我有一些特殊情况,其中计算必须考虑多行。

以下是现在的查询:

SELECT
    UserName
    , EntryDate
    , Project
    , HoursWorked
    , HoursAvailable
    , UtilPct as HoursWorked / HoursAvailable
FROM
    MyDatabase
ORDER BY
    EntryDate

结果是:

UserName EntryDate Project HoursWorked HoursAvailable UtilPct
Justin 12/17/2012 ABC 8 8 100
Justin 12/18/2012 ABC 4 8 50
Justin 12/18/2012 DEF 4 8 50

但最后两个条目的利用率为50%是错误的,因为两者都发生在同一天。这两行都应显示100%。

我需要查询...

  1. 总结某一天所有工作时间
  2. 除以当天的最大HoursAvailable
  3. 将该值放入每行的UtilPct列
  4. 我如何做到这一点?

4 个答案:

答案 0 :(得分:1)

SELECT
    a.Username, 
    a.EntryDate,
    a.Project,
    a.HoursWorked,
    (b.TotalHoursWorked / a.HoursAvailable) * 100 as 'UtilPct'
FROM
    MyDatabase a
INNER JOIN
    (SELECT 
       SUM(HoursWorked) as TotalHoursWorked, 
       Username, 
       EntryDate 
     FROM 
       MyDatabase 
     GROUP BY 
       Username, EntryDate) b
ON
  a.Username = b.Username
  AND a.EntryDate = b.EntryDate

答案 1 :(得分:1)

  

我需要查询...

     

总结某一天的所有工作时间      除以那天的最大HoursAvailable      将该值放入每行的UtilPct列

     

我如何做到这一点?

总结所有工时:

SUM(HoursWorked) ... GROUP BY EntryDate

除以那天的最大HoursAvailable

SUM(HoursWorked)/MAX(HoursAvailable) ... GROUP BY EntryDate

将该值放入每行的UtilPct列中:

SELECT ... SUM(HoursWorked)/MAX(HoursAvailable)*100.0 AS UtilPct
    FROM MyDatabase
    GROUP BY EntryDate
    ORDER BY EntryDate

但现在您无法将行划分为Project,您只会看到任何一天的时间利用率。如果您尝试GROUP BY Project,您将获得50%而不是100%。

那是因为你要求4/8是100%,这会让你获得语义上无意义的答案,例如“周二,我在项目ABC上工作100%,以及 100%项目DEF“,人们可以回答”所以周二有200%的人吗?“

您可以使用表格与其自身之间的JOIN来解决窘境,以便在一天内获得TotalHoursWorked ,这与MonthWorked 在语义上不同在一个项目上

SELECT
    UserName
    , md1.EntryDate
    , Project
    , HoursWorked
    , HoursAvailable
    , (TotalHoursWorked / HoursAvailable)*100.0 AS UtilPct
FROM
    MyDatabase AS md1
    JOIN ( 
        SELECT EntryDate, SUM(HoursWorked) AS TotalHoursWorked
        FROM MyDatabase GROUP BY EntryDate
    ) AS md2 ON (md1.EntryDate = md2.EntryDate)
ORDER BY
    md1.EntryDate

现在,UtilPct将参考当天的时间使用情况,这意味着您可以获得100%的项目价值,即使您只使用了5分钟,只要这五分钟就是您可以使用的那些天。您仍然可以添加另一列来指示 HoursWorked超过HoursAvailable的百分比(在大多数系统中,它应该与该项目的优先级大致成比例。)

答案 2 :(得分:0)

查询:

<强> SQLFIDDLEExample

SELECT
      t.UserName
    , t.EntryDate
    , t.Project
    , t.HoursWorked
    , t.HoursAvailable
    , (SELECT SUM(HoursWorked) 
      FROM MyDatabase 
      WHERE MyDatabase.EntryDate =t.EntryDate)/
      (SELECT MAX(HoursAvailable) 
      FROM MyDatabase 
      WHERE MyDatabase.EntryDate =t.EntryDate) AS UtilPct
FROM
    MyDatabase t
ORDER BY
    t.EntryDate

结果:

| USERNAME |                       ENTRYDATE | PROJECT | HOURSWORKED | HOURSAVAILABLE | UTILPCT |
-------------------------------------------------------------------------------------------------
|   Justin | December, 17 2012 00:00:00+0000 |     ABC |           8 |              8 |       1 |
|   Justin | December, 18 2012 00:00:00+0000 |     ABC |           4 |              8 |       1 |
|   Justin | December, 18 2012 00:00:00+0000 |     DEF |           4 |              8 |       1 |

顺便提一下表中的名字。

答案 3 :(得分:0)

子查询只是总结当天。

        SELECT
              t.UserName
            , t.EntryDate
            , t.Project
            , t.HoursWorked
            , t.HoursAvailable
            , CASE WHEN HoursAvailable = 0 THEN 0 
                   ELSE Round(HoursWorked / HoursAvailable * 100.0, 2) 
                   END AS UtilPct
        FROM
            MyTable t
            INNER JOIN 
              (SELECT EntryDate,
                      UserName,          
                      SUM(HoursWorked) AS HoursWorked,
                      MAX(HoursAvailable) AS HoursAvailable
              FROM MyTable
              GROUP BY EntryDate,
                       UserName) AS Daily
        ON t.EntryDate = Daily.EntryDate
           AND t.UserName = Daily.UserName
        ORDER BY
            t.EntryDate,
            t.UserName