【问题标题】:Sql query to generate monthly pay dates based on a month end dateSql 查询根据月末日期生成每月支付日期
【发布时间】:2017-03-23 02:44:22
【问题描述】:

我想根据一年的“月薪”和“月末”日期生成每月支付日期。假设我选择“01/26/2016”作为“支付日期”和“01/31/2016 " 作为 "月末" 日期和日期范围是 2016 年。 那么“月末”日期将是该年月份的最后一天,支付日期将是 (当月的“月末”日期 - 月份的“支付日期”) th 2016 年全年的月份。我为支付日期“01/26/2016”和“01/31/2016”作为“月底”日期添加了结果集的屏幕截图。我的 SQL 版本是 2012。 我想知道SQL中的查询。

任何帮助将不胜感激。

“02/08/2016”作为“支付日期”和“01/31/2016”作为“月末”的屏幕截图

【问题讨论】:

  • 基本上你需要得到选择的月底日期选择的支付日期之间的日期差并应用与所有其他月份相同。这是你的要求吗?
  • 正确@viki888

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


【解决方案1】:

与您的last question 的逻辑相同。

你可以如下:

DECLARE @StartDate DATETIME = '2016.01.26'
DECLARE @EndDate DATETIME = '2016.01.31'

SELECT
    DATENAME(dw, A.Month) DayNameOfMonth,
    A.[Month],
    DATENAME(dw, A.[Pay Date]) DayNameOfPayDate,
    A.[Pay Date]
FROM
(
    SELECT
         DATEADD(DAY, -1 - (DAY(EOMONTH(@EndDate)) - DAY(@EndDate)),  DATEADD(MONTH, v.m, DATEFROMPARTS(YEAR(@EndDate), 1, 1))) 'Month',
         DATEADD(DAY, -1 - (DAY(EOMONTH(@StartDate)) - DAY(@StartDate)),  DATEADD(MONTH, v.m, DATEFROMPARTS(YEAR(@StartDate), 1, 1))) 'Pay Date'
    FROM
        (VALUES (1), (2), (3), (4), (5), (6), (7), (8), (9), (10), (11), (12)) AS v(m)
) A

结果:

DayNameOfMonth                 Month      DayNameOfPayDate               Pay Date
------------------------------ ---------- ------------------------------ ----------
Sunday                         2016-01-31 Tuesday                        2016-01-26
Monday                         2016-02-29 Wednesday                      2016-02-24
Thursday                       2016-03-31 Saturday                       2016-03-26
Saturday                       2016-04-30 Monday                         2016-04-25
Tuesday                        2016-05-31 Thursday                       2016-05-26
Thursday                       2016-06-30 Saturday                       2016-06-25
Sunday                         2016-07-31 Tuesday                        2016-07-26
Wednesday                      2016-08-31 Friday                         2016-08-26
Friday                         2016-09-30 Sunday                         2016-09-25
Monday                         2016-10-31 Wednesday                      2016-10-26
Wednesday                      2016-11-30 Friday                         2016-11-25
Saturday                       2016-12-31 Monday                         2016-12-26

更新

DECLARE @StartDate DATETIME = '2016.01.31' -- month end
DECLARE @EndDate DATETIME = '2016.02.08' -- pay date

SELECT         
    DATEADD(DAY, -1 - (DAY(EOMONTH(@StartDate)) - DAY(@StartDate)),  DATEADD(MONTH, v.m, DATEFROMPARTS(YEAR(@StartDate), 1, 1))) 'Month End',        
    DATEADD(DAY, DATEDIFF(DAY, @StartDate, @EndDate), DATEADD(DAY, -1 - (DAY(EOMONTH(@StartDate)) - DAY(@StartDate)),  DATEADD(MONTH, v.m, DATEFROMPARTS(YEAR(@StartDate), 1, 1)))) 'Pay Date'
FROM
    (VALUES (1), (2), (3), (4), (5), (6), (7), (8), (9), (10), (11), (12)) AS v(m)

更新 2

DECLARE @StartDate DATETIME = '2016.01.31' -- month end
DECLARE @EndDate DATETIME = '2016.02.08' -- pay date

SELECT
    *
FROM
(
    SELECT         
        DATEADD(DAY, -1 - (DAY(EOMONTH(@StartDate)) - DAY(@StartDate)),  DATEADD(MONTH, v.m, DATEFROMPARTS(YEAR(@StartDate), 1, 1))) 'Month End',        
        DATEADD(DAY, DATEDIFF(DAY, @StartDate, @EndDate), DATEADD(DAY, -1 - (DAY(EOMONTH(@StartDate)) - DAY(@StartDate)),  DATEADD(MONTH, v.m, DATEFROMPARTS(YEAR(@StartDate), 1, 1)))) 'Pay Date'
    FROM
        (VALUES (1), (2), (3), (4), (5), (6), (7), (8), (9), (10), (11), (12)) AS v(m)
) A
WHERE
    YEAR(A.[Pay Date]) = YEAR(@EndDate)

【讨论】:

  • 感谢您的回复,但如果我输入“2016.01.31”作为“月末”日期和“2016.02.08”作为“支付日期”,那么输出与我想要的结果不匹配。 @NEER
  • 只有一个条款需要“PayDate”应该在一年内。 @NEER
  • 再次感谢... :) @NEER
【解决方案2】:

试试这个

DECLARE @PayDate AS DATE = '2016-Jan-26', @MonthEndDate AS DATE = '2016-Jan-31'
DECLARE @Start AS INT = 0, @End AS INT = 11
DECLARE @DateDiff AS INT = (SELECT DATEDIFF(DAY, @PayDate, @MonthEndDate))

; WITH CTE AS
(
SELECT @Start as number
UNION ALL
SELECT number + 1
FROM CTE
WHERE number < @End
) SELECT 

DATENAME(dw, DATEADD(MONTH, number, @MonthEndDate)) + ', ' + convert(varchar(12), DATEADD(MONTH, number, @MonthEndDate), 113) AS MonthEnd, 
DATENAME(dw, DATEADD(DAY, -@DateDiff, DATEADD(MONTH, number, @MonthEndDate))) + ', ' + convert(varchar(12), DATEADD(DAY, -@DateDiff, DATEADD(MONTH, number, @MonthEndDate)), 113) AS PayDate 
FROM CTE

/* Output:
MonthEnd                    PayDate
---------------------------------------------------
Sunday, 31 Jan 2016         Tuesday, 26 Jan 2016
Monday, 29 Feb 2016         Wednesday, 24 Feb 2016
Thursday, 31 Mar 2016       Saturday, 26 Mar 2016
Saturday, 30 Apr 2016       Monday, 25 Apr 2016
Tuesday, 31 May 2016        Thursday, 26 May 2016
Thursday, 30 Jun 2016       Saturday, 25 Jun 2016
Sunday, 31 Jul 2016         Tuesday, 26 Jul 2016
Wednesday, 31 Aug 2016      Friday, 26 Aug 2016
Friday, 30 Sep 2016         Sunday, 25 Sep 2016
Monday, 31 Oct 2016         Wednesday, 26 Oct 2016
Wednesday, 30 Nov 2016      Friday, 25 Nov 2016
Saturday, 31 Dec 2016       Monday, 26 Dec 2016
*/

【讨论】:

  • 只需要一次更改,“PayDate”应该在一年内。请查看编辑后的问题@Tanjim Rahman
  • 您要问的是简单的逻辑更改可以通过@DateDiff 的某些条件完成。
【解决方案3】:
DECLARE @Y int = 2016;

SELECT RD.ME MonthEnd, RD.PD PayDate FROM 
(select
 1 as mth 
union 
select 2 
union 
select 3 
union 
select 4 
union 
select 5
union 
select 6
union 
select 7 
union 
select 8
union 
select 9
union 
select 10 
union 
select 11
union 
select 12) M 
CROSS APPLY (SELECT DATEADD(month, M.mth - 1, DATEADD(year, @y - 1900, 0)) RM ) OA
CROSS APPLY (SELECT DATEADD(day, -1 , DATEADD(month, 1, OA.RM)) ME,  DATEADD(day, -6 , DATEADD(month, 1, OA.RM)) PD) RD ORDER BY RD.ME

【讨论】:

    猜你喜欢
    • 2017-03-22
    • 2021-10-08
    • 2010-09-11
    • 2021-12-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多