在不同表的临时表中添加列名称,并根据这些列进行过滤

问题描述 投票:0回答:1

在我在表中生成报告的存储过程中

Age
,用户可以定义需要获取日期范围数据的日期范围。表
Age
AgeDesc
StartDay
EndDay
。请检查此处显示的示例:

桌子

Age

AgeDesc         StartDay    EndDay
-----------------------------------
 < 30            0          30
 >30 < 60        30         60
 >60 < 90        60         90
 >90 < 120       90         120

在我的存储过程中,我创建了一个临时表,如下所示,并将年龄表中的其余列添加到临时表中

CREATE TABLE #Bills 
(
    LedgerId INT, 
    LedgerName varchar(300),
    InvoiceNumber Varchar(50), 
    InvoiceDate DATETIME,
)

DECLARE @dynamicColumn nvarchar(max)

SELECT @dynamicColumn = STRING_AGG(QUOTENAME(AgeDesc),',')
FROM tblAge 

-- SELECT @dynamicColumn
DECLARE @addColumn nvarchar(max);

SELECT @addColumn = STRING_AGG(' ALTER TABLE #Bills ADD ' + QUOTENAME(AgeDESC) + ' VARCHAR(100) NULL; ',' ') 
FROM tblAge         

EXEC sp_executesql @addColumn

SELECT * FROM #Bills

#Bills
中选择后,我得到了列名称,因为这是完美的

LedgerId | LedgerName | InvoiceNumber | InvoiceDate | < 30 |  >30 < 60 | >60 < 90 | >90 < 120

现在我想按照 tblAge 中为每列定义的天数从我的 select 语句中将数据插入 #bill 中,例如

<30 days     InvoiceDate <= GETDATE()  AND InvoiceDate >= GETDATE()-30 
for >30 <60  InvoiceDate  < GETDATE()-30  AND InvoiceDate >= GETDATE()-60
For >60 < 90 InovoiceDate < GETDATE()-60  AND InvoiceDAte >= GETDATE()-90
for >90 < 120 InovoiceDate < GETDATE()-90  AND InoviceDate >= GETDATE()-120

INSERT INTO @Bills
    SELECT * FROM 
             L.LedgerId
            ,L.LedgerName
            ,B.InvoiceNumber, 
             B.InvoiceDate
          rest for newly added column value as per provided details

我该怎么做?用户可以插入不同日期范围的多行,这些行将自动添加到 #Bills 表中,所以我正在使用它。

请向我提供您的建议或示例。我真的会很感激。

stored-procedures dynamic-columns sql-server-2022
1个回答
0
投票

您没有在各个年龄栏下提到您想要什么。所以我假设

InvoiceAmount

使用

CROSS APPLY
来确定
Invoice
的“年龄”,并使用条件case表达式进行透视,就可以得到所需的结果格式。

查询看起来像这样

; with
InvoiceAged as
(
  select b.InvoiceNumber,
         b.InvoiceDate,
         b.InvoiceAmount,
         a.age
  from   Bills b
         cross apply
         (
             select age = a.StartDay
             from   tblAge a
             where  a.StartDay <= datediff(day, b.InvoiceDate, getdate())
             and    a.EndDay    > datediff(day, b.InvoiceDate, getdate())
         ) a
)
select InvoiceNumber, InvoiceDate,
       SUM(CASE WHEN age = 0 THEN InvoiceAmount END) AS [< 30],
       SUM(CASE WHEN age = 30 THEN InvoiceAmount END) AS [>30 < 60],
       SUM(CASE WHEN age = 60 THEN InvoiceAmount END) AS [>60 < 90],
       SUM(CASE WHEN age = 90 THEN InvoiceAmount END) AS [>90 < 120]
from   InvoiceAged
group by InvoiceNumber, InvoiceDate

并使其充满活力

年龄条件case表达式查询

declare @age nvarchar(max);

select  @age = STRING_AGG('SUM(CASE WHEN age = ' + CONVERT(VARCHAR(10), StartDay) + ' THEN InvoiceAmount END) AS ' + QUOTENAME(AgeDesc), ',' + char(13)) 
FROM    tblAge 

以及其余的查询

declare @sql nvarchar(max);

select @sql = '
; with
InvoiceAged as
(
  SELECT b.InvoiceNumber,
         b.InvoiceDate,
         b.InvoiceAmount,
         a.age
  FROM   Bills b
         cross apply
         (
             select age = a.StartDay
             from   tblAge a
             where  a.StartDay <= datediff(day, b.InvoiceDate, getdate())
             and    a.EndDay    > datediff(day, b.InvoiceDate, getdate())
         ) a
)
select InvoiceNumber, InvoiceDate,'
       + @age +
' from   InvoiceAged
group by InvoiceNumber, InvoiceDate'
© www.soinside.com 2019 - 2024. All rights reserved.