gpt4 book ai didi

sql-server - 具有联接和动态列的 SQL SERVER PIVOT 表

转载 作者:行者123 更新时间:2023-12-03 01:23:59 36 4
gpt4 key购买 nike

我有一个查询需要转换,但遇到了麻烦。

SQL Server 版本为 2005 和 2008。

查询源自公共(public)表表达式

DECLARE 
@cols AS NVARCHAR(MAX),
@query AS NVARCHAR(MAX),
@in_iYearFrom int, @in_iYearTo int,
@in_iMonthFrom int, @in_iMonthTo int,
@in_vsPlanID varchar(100)
@cols AS NVARCHAR(MAX),
@query AS NVARCHAR(MAX),
@in_iYearFrom int, @in_iYearTo int,
@in_iMonthFrom int, @in_iMonthTo int,
@in_vsPlanID varchar(100)

SELECT
@in_iYearFrom = 2012, @in_iYearTo = 2013, @in_iMonthFrom = 11, @in_iMonthTo = 2, @in_vsPlanID = '25,28'

select @cols = STUFF(
(SELECT DISTINCT
',' + QUOTENAME(Convert(varchar(4),Year(b.run_date)) + ', ' + DateName(month,b.run_date)) AS run_date
FROM tblBill b
WHERE b.plan_id IN (SELECT * FROM dbo.fnStringToTable(@in_vsPlanID,','))
AND Year(b.run_date) * 100 + MONTH(b.run_date) >= @in_iYearFrom * 100 + @in_iMonthFrom
AND Year(b.run_date) * 100 + MONTH(b.run_date) <= @in_iYearTo * 100 + @in_iMonthTo
GROUP BY b.run_date
ORDER BY run_date
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')

SET @query = N'
;WITH cteBills (total_premium, run_month, run_year, plan_id) AS
(
SELECT
SUM(Round(ebs.employee_premium,2) + Round(ebs.employer_premium,2) +
Round(ebs.ee_tax_prov,2) + Round(ebs.er_tax_prov,2) +
Round(ebs.ee_tax_fed,2) + Round(ebs.er_tax_fed,2) +
Round(ebs.ee_tax_hst,2) + Round(ebs.er_tax_hst,2)
) AS total_premium,
Month(b.run_date), Year(b.run_date), b.plan_id
FROM EmpBillStatement ebs
INNER JOIN tblBillStatementBenefit bsb ON bsb.billstatementbenefit_id = ebs.billstatementbenefit_id
INNER JOIN tblBillStatement bs ON bs.billstatement_id = bsb.billstatement_id
INNER JOIN tblBill b ON b.bill_id = bs.bill_id
WHERE b.plan_id IN (SELECT * FROM dbo.fnStringToTable(@vsPlanID, '',''))
AND Year(b.run_date) * 100 + MONTH(b.run_date) >= @iYearFrom * 100 + @iMonthFrom
AND Year(b.run_date) * 100 + MONTH(b.run_date) <= @iYearTo * 100 + @iMonthTo
AND b.confirmed_bill = 1
GROUP BY b.plan_id, Month(b.run_date), Year(b.run_date)
),
cteBillsAdj (total_adj, run_month, run_year, plan_id) AS
(
SELECT
SUM(
Round(ISNULL(adjust_cost_er,0),2) +
Round(ISNULL(adjust_cost_ee,0),2) +
Round(ISNULL(adjust_tax_ee_prov,0),2) +
Round(ISNULL(adjust_tax_er_prov,0),2) +
Round(ISNULL(adjust_tax_ee_hst,0),2) +
Round(ISNULL(adjust_tax_er_hst,0),2) +
Round(ISNULL(adjust_tax_ee_fed,0),2) +
Round(ISNULL(adjust_tax_er_fed,0),2)
) AS total_premium,
Month(b.run_date), Year(b.run_date), b.plan_id
FROM tblBillAdjustmentBenefit e
INNER JOIN tblBillAdjustment ba ON (ba.billadjustment_id = e.billadjustment_id)
INNER JOIN tblBillStatementBenefit bsb ON bsb.billstatementbenefit_id = e.billstatementbenefit_id
INNER JOIN tblBillStatement bs ON bs.billstatement_id = bsb.billstatement_id
INNER JOIN tblBill b ON b.bill_id = bs.bill_id
WHERE b.plan_id IN (SELECT * FROM dbo.fnStringToTable(@vsPlanID, '',''))
AND Year(b.run_date) * 100 + MONTH(b.run_date) >= @iYearFrom * 100 + @iMonthFrom
AND Year(b.run_date) * 100 + MONTH(b.run_date) <= @iYearTo * 100 + @iMonthTo
AND b.confirmed_bill = 1
GROUP BY b.plan_id, Month(b.run_date), Year(b.run_date)
)
select plan_id, ' + @cols + '
from
(
SELECT
b.plan_id,
(Convert(varchar(4),b.run_year) + '', '' + DateName(month,CAST(''1900-'' + Convert(varchar(2),b.run_month) + ''-01'' AS DATETIME))) AS billdate,
ISNULL(b.total_premium,0) + ISNULL(a.total_adj,0) AS total
FROM cteBills b
LEFT JOIN cteBillsAdj a
ON a.run_month = b.run_month
AND b.run_year = a.run_year
AND b.plan_id = a.plan_id
) d
pivot
(
sum(total)
for billdate in (' + @cols + ')
) piv;
'
execute sp_executesql @query, N'@iYearFrom int, @iYearTo int, @iMonthFrom int, @iMonthTo int, @vsPlanID varchar(100)',
@in_iYearFrom, @in_iYearTo, @in_iMonthFrom, @in_iMonthTo, @in_vsPlanID;

数据显示如下

plan_id     billdate                             total
----------- ------------------------------------ -------------
25 2012, November 60117.56000
25 2012, December 61515.17000
25 2013, January 60791.62000
25 2013, February 60745.29000
28 2012, November 1564.69000
28 2012, December 1564.69000
28 2013, January 1564.69000
28 2013, February 1590.44000

我需要它采用这种格式

plan_id     2012, November   2012, December   2013, January   2013, February
-----------------------------------------------------------------------------
25 60117.56000 61515.17000 60791.62000 60745.29000
28 1564.69000 1564.69000 1564.69000 1590.44000

可以有更多的 plan_id 和更多的日期来跨越。

提前谢谢

最佳答案

由于您想要将数据从行转换为列,那么您将需要使用 PIVOT功能。如果您的数量有限或已知值,则可以对查询进行硬编码:

select plan_id, [2012, November], [2012, December], [2013, January], [2013, February]
from
(
SELECT
b.plan_id,
(Convert(varchar(4),b.run_year) + ', ' + DateName(month,CAST('1900-' + Convert(varchar(2),b.run_month) + '-01' AS DATETIME))) AS billdate,
ISNULL(b.total_premium,0) + ISNULL(a.total_adj,0) AS total
FROM cteBills b
LEFT JOIN cteBillsAdj a
ON a.run_month = b.run_month
AND b.run_year = a.run_year
AND b.plan_id = a.plan_id
) d
pivot
(
sum(total)
for billdate in ([2012, November], [2012, December], [2013, January], [2013, February])
) piv;

但是如果您有未知数量的值,那么您将需要实现动态 SQL:

DECLARE @cols AS NVARCHAR(MAX),
@query AS NVARCHAR(MAX)

select @cols = STUFF((SELECT ',' + QUOTENAME(Convert(varchar(4),b.run_year) + ', ' + DateName(month,CAST('1900-' + Convert(varchar(2),b.run_month) + '-01' AS DATETIME))) )
from cteBills
group by b.run_year, b.run_month
order by b.run_year, b.run_month
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')

set @query = 'SELECT plan_id, ' + @cols + '
from
(
SELECT
b.plan_id,
(Convert(varchar(4),b.run_year) + '', '' + DateName(month,CAST(''1900-'' + Convert(varchar(2),b.run_month) + ''-01'' AS DATETIME))) AS billdate,
ISNULL(b.total_premium,0) + ISNULL(a.total_adj,0) AS total
FROM cteBills b
LEFT JOIN cteBillsAdj a
ON a.run_month = b.run_month
AND b.run_year = a.run_year
AND b.plan_id = a.plan_id
) x
pivot
(
sum(total)
for billdate in (' + @cols + ')
) p '

execute sp_executesql @query;

关于sql-server - 具有联接和动态列的 SQL SERVER PIVOT 表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18317732/

36 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com