【问题标题】:SQL Server : return distinct number of periodsSQL Server:返回不同的周期数
【发布时间】:2017-11-03 21:28:21
【问题描述】:

我们有以下 SQL Server 2008 示例数据库表,其中显示了每个员工在每个支付期的工资信息(每周支付,因此每年 52 或 53 周,在英国纳税年度之后,因此支付期第 1 周是 4 月 6 日及以后)。

我将样本限制在一个员工的薪酬周期范围内,实际数据可以追溯到多年前。

我需要为每个员工生成查询运行后过去 12 周的工资总额。

+------------+------------+---------+-------+
| EMPLOYEEID | PAYELEMENT | AMOUNT  | HOURS |
+------------+------------+---------+-------+
|     160062 | 1.0 Basic  | 2724.64 |   468 |
+------------+------------+---------+-------+

但是,由于以下原因,我在追溯 12 个不同时期时遇到了一些问题......

  1. 期间 1 有两个条目
  2. 放假时没有记录期间,例如第 30 周、第 38 周和第 39 周缺失。在这种情况下,它需要返回,直到使用了 12 个记录周期。
  3. 从第 52 期到第 1 期结束年终

我尝试使用每个员工的最后 12 条记录,但上面的第 1 项仅导致计算 11 个期间。

我也尝试过在支付日使用日期差异,但上面的第 2 项导致缺少期间。

我是否需要为每个员工添加一个索引来显示 12 个单独的时期?

+------------+------------+------+--------+--------+-------+------+------------------+
| EMPLOYEEID | PAYELEMENT | YEAR | PERIOD | AMOUNT | HOURS | RATE |     PAYDATE      |
+------------+------------+------+--------+--------+-------+------+------------------+
|     160062 | 1.0 Basic  | 2017 |     29 | 311.22 |    39 | 7.98 | 20/10/2016 00:00 |
|     160062 | 1.0 Basic  | 2017 |     31 | 311.22 |    39 | 7.98 | 03/11/2016 00:00 |
|     160062 | 1.0 Basic  | 2017 |     32 | 311.22 |    39 | 7.98 | 10/11/2016 00:00 |
|     160062 | 1.0 Basic  | 2017 |     33 | 311.22 |    39 | 7.98 | 17/11/2016 00:00 |
|     160062 | 1.0 Basic  | 2017 |     34 | 311.22 |    39 | 7.98 | 24/11/2016 00:00 |
|     160062 | 1.0 Basic  | 2017 |     35 | 311.22 |    39 | 7.98 | 01/12/2016 00:00 |
|     160062 | 1.0 Basic  | 2017 |     36 | 183.54 |    23 | 7.98 | 08/12/2016 00:00 |
|     160062 | 1.0 Basic  | 2017 |     37 | 311.22 |    39 | 7.98 | 15/12/2016 00:00 |
|     160062 | 1.0 Basic  | 2017 |     40 | 311.22 |    39 | 7.98 | 05/01/2017 00:00 |
|     160062 | 1.0 Basic  | 2017 |     41 | 311.22 |    39 | 7.98 | 12/01/2017 00:00 |
|     160062 | 1.0 Basic  | 2017 |     42 | 311.22 |    39 | 7.98 | 19/01/2017 00:00 |
|     160062 | 1.0 Basic  | 2017 |     43 | 311.22 |    39 | 7.98 | 26/01/2017 00:00 |
|     160062 | 1.0 Basic  | 2017 |     44 | 311.22 |    39 | 7.98 | 02/02/2017 00:00 |
|     160062 | 1.0 Basic  | 2017 |     45 | 311.22 |    39 | 7.98 | 09/02/2017 00:00 |
|     160062 | 1.0 Basic  | 2017 |     46 | 311.22 |    39 | 7.98 | 16/02/2017 00:00 |
|     160062 | 1.0 Basic  | 2017 |     47 | 311.22 |    39 | 7.98 | 23/02/2017 00:00 |
|     160062 | 1.0 Basic  | 2017 |     48 | 127.68 |    16 | 7.98 | 02/03/2017 00:00 |
|     160062 | 1.0 Basic  | 2017 |     49 | 311.22 |    39 | 7.98 | 09/03/2017 00:00 |
|     160062 | 1.0 Basic  | 2017 |     50 | 247.38 |    31 | 7.98 | 16/03/2017 00:00 |
|     160062 | 1.0 Basic  | 2017 |     51 | 311.22 |    39 | 7.98 | 23/03/2017 00:00 |
|     160062 | 1.0 Basic  | 2017 |     52 | 311.22 |    39 | 7.98 | 30/03/2017 00:00 |
|     160062 | 1.0 Basic  | 2018 |      1 | 247.38 |    31 | 7.98 | 06/04/2017 00:00 |
|     160062 | 1.0 Basic  | 2018 |      1 |      0 |     0 | 7.75 | 06/04/2017 00:00 |
|     160062 | 1.0 Basic  | 2018 |      2 | 311.22 |    39 | 7.98 | 13/04/2017 00:00 |
|     160062 | 1.0 Basic  | 2018 |      3 | 255.36 |    32 | 7.98 | 20/04/2017 00:00 |
|     160062 | 1.0 Basic  | 2018 |      4 | 247.38 |    31 | 7.98 | 27/04/2017 00:00 |
|     160062 | 1.0 Basic  | 2018 |      5 | 311.22 |    39 | 7.98 | 04/05/2017 00:00 |
|     160062 | 1.0 Basic  | 2018 |      6 | 127.68 |    16 | 7.98 | 11/05/2017 00:00 |
|     160062 | 1.0 Basic  | 2018 |      7 | 247.38 |    31 | 7.98 | 18/05/2017 00:00 |
|     160062 | 1.0 Basic  | 2018 |      8 | 277.31 | 34.75 | 7.98 | 25/05/2017 00:00 |
+------------+------------+------+--------+--------+-------+------+------------------+

【问题讨论】:

  • 您可以从 PAYDATE 中取出一个月或一周作为您的经期吗?
  • 以上示例输出中的amounthours 总数是否正确?
  • 这只是 12 周范围内显示的示例,可以是任何金额,具体取决于工作时间和工资
  • 您是选择特定员工的期间还是从指定日期开始?
  • 从特定日期开始

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


【解决方案1】:

你应该试试:

;WITH Top12Periods AS (
    SELECT TOP 12 [YEAR], [PERIOD]
    FROM @employeeTable
    GROUP BY [YEAR], [PERIOD]
    ORDER BY [YEAR] DESC, [PERIOD] DESC
)
SELECT [EMPLOYEEID], [PAYELEMENT], SUM([AMOUNT]) AS TOTAL_AMOUNT, SUM([HOURS]) AS TOTAL_HOURS, AVG([RATE]) AS AVERAGE_RATE, MIN ([PAYDATE]) [MIN_PAYDATE]
FROM @employeeTable et
    JOIN Top12Periods p ON et.[YEAR] = p.[YEAR] AND et.[PERIOD] = p.[PERIOD]
GROUP BY [EMPLOYEEID], [PAYELEMENT]

【讨论】:

  • 如果 OP 想要一次返回多个员工,这是行不通的。
  • 是的,你完全正确。我正在更正请求。
  • 嗯,但如果员工在不同时期获得报酬,则修正后的答案将不起作用。
【解决方案2】:

这是另一种方法:

SELECT
    EmployeeID,
    PayElement,
    sum(Amount) as Amount,
    sum(Hours) as Hours
FROM
    (
    SELECT *
    ,dense_rank() OVER (PARTITION BY EmployeeId ORDER BY PayDate DESC) as rank
    FROM
        Pay
    ) ranked
WHERE
    rank <= 12
GROUP BY
    EmployeeID,
    PayElement

如果您的零值在这里引起问题,那么只需将WHERE Amount &gt; 0(或者可能是&lt;&gt; 0)添加到内部查询中。根据您的数据,您可能还需要将PayElement 添加到Partition By 子句(或内部WHERE 子句)。

您可以在 rextester.com/YDBL47689 上进行测试

【讨论】:

    猜你喜欢
    • 2012-02-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-10-09
    相关资源
    最近更新 更多