【问题标题】:How to find the first column in an ACCESS table row with a value not Zero of Blank?如何在 ACCESS 表行中找到值不为零的空白的第一列?
【发布时间】:2013-11-21 16:04:43
【问题描述】:

我有一个表格,其中包含为期四年的每个月(1 月 13 日、2 月 13 日、3 月 13 日等)的列。我需要在每一行中找到除“0”(零)以外的值的第一列。然后我需要找到最后一列的值不是零。

查询将让我知道资源的开始月份和结束月份。我已经编写了一个 Excel 公式,但现在我需要将相同的功能转换为 Access。当我找到每一列时,我需要检索列标题。谁能帮我查询查询的 SQL?

基于查询的报告将是

ResourceName, StartDate EndDate
Bob Sample    Apr-13    Apr-15 

实际上涉及两个表。包含个人所有信息的资源表和以月份为列的预测表以及行为资源 ID 和任务的预测表。对于每个月,预计个人将在给定百分比的时间内工作。我们不关心个人开始的实际日期(201 年 11 月 20 日),只关心月份。因此,任务 1 的资源预计在 11 月 13 日工作时间的 0.5%,这将是资源工作的第一个月。然后可以预测该资源在接下来的九个月内以相同的水平工作。因此,8 月 14 日的列将是最后一个月,值为 0.5。之后,所有列都包含零。

【问题讨论】:

    标签: sql ms-access


    【解决方案1】:

    (我将示例限制为六个月,因为我很懒惰。)

    所以我们在名为 [Forecast] 的表中有一些“宽”数据:

    ResourceID  Jul-13  Aug-13  Sep-13  Oct-13  Nov-13  Dec-13
    ----------  ------  ------  ------  ------  ------  ------
             1       0     0.5       1     0.5       0       0
             2       0       0       2       0       0       0
             3       0       0       3       4       0       0
    

    首先在 Access 中创建一个名为 [ForecastUnpivoted] 的已保存查询,以将“短宽”数据转换为“长窄”数据:

        SELECT ResourceID, "2013-07" AS forecastMonth, [Jul-13] AS forecastValue
        FROM Forecast
    UNION ALL
        SELECT ResourceID, "2013-08" AS forecastMonth, [Aug-13] AS forecastValue
        FROM Forecast
    UNION ALL
        SELECT ResourceID, "2013-09" AS forecastMonth, [Sep-13] AS forecastValue
        FROM Forecast
    UNION ALL
        SELECT ResourceID, "2013-10" AS forecastMonth, [Oct-13] AS forecastValue
        FROM Forecast
    UNION ALL
        SELECT ResourceID, "2013-11" AS forecastMonth, [Nov-13] AS forecastValue
        FROM Forecast
    UNION ALL
        SELECT ResourceID, "2013-12" AS forecastMonth, [Dec-13] AS forecastValue
        FROM Forecast
    

    返回

    ResourceID  forecastMonth  forecastValue
    ----------  -------------  -------------
             1  2013-07                    0
             2  2013-07                    0
             3  2013-07                    0
             1  2013-08                  0.5
             2  2013-08                    0
             3  2013-08                    0
             1  2013-09                    1
             2  2013-09                    2
             3  2013-09                    3
             1  2013-10                  0.5
             2  2013-10                    0
             3  2013-10                    4
             1  2013-11                    0
             2  2013-11                    0
             3  2013-11                    0
             1  2013-12                    0
             2  2013-12                    0
             3  2013-12                    0
    

    现在我们可以使用 Min() 和 Max() 为我们提供每个资源的开始结束日期

    SELECT 
        ResourceID, 
        Min(forecastMonth) AS StartMonth, 
        Max(forecastMonth) AS EndMonth
    FROM ForecastUnpivoted
    WHERE forecastValue <> 0
    GROUP BY ResourceID
    

    这给了我们

    ResourceID  StartMonth  EndMonth
    ----------  ----------  --------
             1  2013-08     2013-10 
             2  2013-09     2013-09 
             3  2013-09     2013-10 
    

    【讨论】:

    • 我很欣赏您的解决方案,但您和我都知道这绝不是一个功能性数据库结构 ;-)
    【解决方案2】:

    在关系数据库中,您不会像这样存储数据。相反,您将有 2 个表:

    1. 您的资源
    2. 资源工作的月份(针对任务)

    示例:

    表 1 资源:

    ID | Resource_Name
    1  | Mr. A
    2  | Mrs. B
    

    表 2 预测:

    FC_ID | FC_Month   | FC_Resource_ID | FC_Task     | FC_Percentage
    1     | 2013-10-01 | 1              | actiontask! | 0.05
    2     | 2013-11-01 | 1              | actiontask! | 0.10
    3     | 2013-12-01 | 1              | actiontask! | 0.05
    4     | 2013-07-01 | 2              | boring task | 0.3
    5     | 2013-08-01 | 2              | boring task | 0.25
    6     | 2013-09-01 | 2              | boring task | 0.3
    7     | 2013-10-01 | 2              | boring task | 0.1
    

    然后您可以使用 SQL 请求开始和结束日期:

    SELECT Resource_Name, Min(FC_Month) AS colMin, Max(FC_Month) As colMax 
    FROM tblForecast INNER JOIN tblResources ON FC_Resource_ID=Resource_ID
    GROUP BY FC_Resource_ID, Resource_Name
    

    此示例的结果将是:

    Mr. A  | 2013-10-01 | 2013-12-01
    Mrs. B | 2013-07-01 | 2013-10-01
    

    【讨论】:

    • 马库斯,感谢您的快速回复。请查看我添加到问题中的其他信息。
    • @TerryTewell 我阅读了您的附加信息,您可以完全按照我的建议解决这个问题。表 1 将是您的“资源表”,表 2 将是您的“预测表”。唯一的区别是,在“预测表”中,您将有 4 列:ID、日期(又名月份)、Resource_ID 和任务。每个资源/任务/月份组合将在预测表中占据一行。请不要创建以月份为列的表格。您将不断需要添加更多列(随着时间的推移),这很麻烦且容易出错。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-02-19
    • 2016-10-13
    • 1970-01-01
    • 2018-04-26
    • 1970-01-01
    相关资源
    最近更新 更多