繁体   English   中英

如何根据 SQL 服务器中的条件列动态分配所有月份?

[英]How to dynamically allocate all months based to a column on condition in SQL Server?

我有一张表格,其中存储了Product NameRenewal Date以及付款计划(Monthly/Quarterly/Yearly) 现在,如果产品的付款计划是Yearly or Monthly ,它将显示获取续订月份并显示该月的Rate/Amount ,但如果付款计划是Monthly ,它应该在每个月的前面显示Rate/Amount如下图所示。

例如,如果一个名为ABC的产品的付款计划为Yearly ,订阅率为276Renewal Date 2019-12-01 ,而另一个产品XYZ的付款计划为Monthly ,订阅率为17Renewal Date 2019-08-15 ,那么我想要的结果集应该是这样的

ProductName    RenewalMonth   Rate
------------------------------------
ABC            December       276
XYZ            January         17
XYZ            February        17
XYZ            March           17
XYZ            April           17
XYZ            May             17
XYZ            June            17
XYZ            July            17
XYZ            August          17
XYZ            September       17
XYZ            October         17
XYZ            November        17
XYZ            December        17

这是我编写的查询,它返回数据库中存在的数据,但不是十二月以外的月份Product XYZ 请记住,这应该只显示在付款计划为'Monthly'的所需日期中提供的所有其他月份的相同费率,对于其他付款计划,它应该在数据库中显示的给定月份前面显示费率。

样本数据如下:

CREATE TABLE ItemDefinition 
(
    ID INT NOT NULL,
    ProductName VARCHAR(50),
    PaymentPlan VARCHAR(50),
    RenewalDate DATETIME,
    UnitRate NUMERIC(18, 0)
);

INSERT INTO ItemDefinition 
VALUES (1, 'ABC', 'Yearly', '2019-12-01', 276),
       (1, 'XYZ', 'Monthly', '2019-08-15', 17);

我正在写的查询是

SELECT 
    ProductName, SUM(UnitRate) Rate,
    DATENAME(MONTH , DATEADD(MONTH , MONTH(RenewalDate)-1 , '1900-01-01')) RenewalMonth
FROM
    ItemDefinition 
WHERE 
    MONTH(RenewalDate) IS NOT NULL
    AND RenewalDate BETWEEN @dtStart AND @dtEnd
GROUP BY 
    ProductName, MONTH(RenewalDate)
ORDER BY 
    MONTH(RenewalDate)

如图所示,“<code>Office 365 Essential</code>”根据我的记录有 <code>Monthly</code> 订阅,因此必须在每个月下显示。

它可能是这样的:

DECLARE @DateBeg DATE = '2019-01-01'
       ,@DateEnd DAte = '2020-12-01';


WITH Ranges AS
(
    SELECT *
          ,@DateBeg AS [DateBeg]
          ,@DateEnd AS [DateEnd]
    FROM ItemDefinition DS
)
SELECT *
      ,DATENAME(MONTH ,ISNULL([GeneratedDate], [RenewalDate])) AS RenewalMonth
FROM Ranges
OUTER APPLY
(
    SELECT DATEADD(MONTH, [number], [DateBeg])
    FROM 
    (
        select number 
        from master.dbo.spt_values
        where [type] = 'P'
    ) numbers
    WHERE DATEADD(MONTH, [number], [DateBeg]) < [DateEnd]
        AND [PaymentPlan] = 'Monthly'
) AutoDates ([GeneratedDate]);

您可以将DateEnd参数更改为更少,您将看到生成的月份数减少了多少。

这个想法是为每一行设置startend日期,并根据它来生成你的月份。


要获取这些年的记录,请使用以下命令:

WITH Ranges AS
(
    SELECT *
          ,@DateBeg AS [DateBeg]
          ,@DateEnd AS [DateEnd]
    FROM ItemDefinition DS
)
SELECT *
      ,DATENAME(MONTH ,ISNULL([GeneratedDate], [RenewalDate])) AS RenewalMonth
      ,IIF([PaymentPlan] = 'Monthly', [UnitRate], IIF(CONVERT(VARCHAR(7), [RenewalDate], 121) = CONVERT(VARCHAR(7), [GeneratedDate], 121), [UnitRate], NULL))
FROM Ranges
OUTER APPLY  
(
    SELECT DATEADD(MONTH, [number], [DateBeg])
    FROM 
    (
        select number 
        from master.dbo.spt_values
        where [type] = 'P'
    ) numbers
    WHERE DATEADD(MONTH, [number], [DateBeg]) < [DateEnd]
) AutoDates ([GeneratedDate]);

或以下获取第一条记录的年率:

DECLARE @DateBeg DATE = '2019-01-01'
       ,@DateEnd DAte = '2020-12-01';


WITH Ranges AS
(
    SELECT *
          ,@DateBeg AS [DateBeg]
          ,@DateEnd AS [DateEnd]
    FROM ItemDefinition DS
)
SELECT *
      ,DATENAME(MONTH ,ISNULL([GeneratedDate], [RenewalDate])) AS RenewalMonth
      ,IIF([PaymentPlan] = 'Monthly', [UnitRate], IIF([number] = 0, [UnitRate], NULL))
FROM Ranges
OUTER APPLY  
(
    SELECT DATEADD(MONTH, [number], [DateBeg])
          ,[number]
    FROM 
    (
        select number 
        from master.dbo.spt_values
        where [type] = 'P'
    ) numbers
    WHERE DATEADD(MONTH, [number], [DateBeg]) < [DateEnd]
) AutoDates ([GeneratedDate], [number]);

我的建议是引入一个附加表,该表将有一条记录用于年度计划和 12 条记录用于月度计划。 例如:

create table PaymentPlanInterval(
    PaymentPlan VARCHAR(50),
    Interval varchar(50)
)

也许这个表可能包含 2 条半年支付计划的记录和 4 条季度计划的记录。

为了获得您想要的结果,您应该使用 PaymentPlanInterval 加入您的 ItemDefinition 表。 瞧。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM