在 SQL 查询中使用声明的变量时出错
Error when using a declared variable in SQL Query
我每 cnsmr_accnt_id 付款几个月。我希望查看过去 4 个月每月的总付款额。像这样:
Cnsmr_accnt_id | Wrkgrp_nm | Apr15_Tot | May15_Tot | Jun15_Tot | Jul15_Tot
12345 |Workgrp1 | 123424 | 1243255 | 232342 | 23232323
12347 |Workgrp4 | 123323 | 1244455 | 324342 | 232323
我正在尝试使用 Pivot 来执行此操作,但在使用以下代码时一直出现错误。我怀疑这与变量@Dates 范围有关。
@Dates 给我的值是 Apr15、May15、Jun15、Jul15,这是正确的。
如果我将其直接替换为 Select 代替 @Dates,则查询有效。但是当我使用@Dates 时,它会出错。 (“@Dates”附近的语法不正确。)
我也试过将用于设置@Dates 的整个"formula" 放入select 语句中,但这也会出错。 (关键字 'left' 附近的语法不正确)
Declare @Dates as nvarchar(max);
--Builds up a string of dates for the last 4 months.
Set @Dates = left(datename(Month, datefromparts(year(dateadd(month, -3, getdate())), month(getdate())-3, 1)), 3) +
right(datename(year, datefromparts(year(dateadd(month, -3, getdate())), month(getdate())-3, 1)), 2) + ',' +
left(datename(Month, datefromparts(year(dateadd(month, -2, getdate())), month(getdate())-2, 1)), 3) +
right(datename(year, datefromparts(year(dateadd(month, -2, getdate())), month(getdate())-2, 1)), 2)+ ',' +
left(datename(Month, datefromparts(year(dateadd(month, -1, getdate())), month(getdate())-1, 1)), 3) +
right(datename(year, datefromparts(year(dateadd(month, -1, getdate())), month(getdate())-1, 1)), 2)+ ',' +
left(datename(Month, getdate()), 3) +
right(datename(year, getdate()), 2);
--Print @dates
--Example output = Apr15,May15,Jun15,Jul15
--Use a pivot to get the totals per cnsmr_accnt_id for the last 4 months.
Select *
from
(
Select
capj.cnsmr_accnt_id,
wrkgrp_nm,
max(UDEFINST_AMT) as Instlmnt,
sum(cnsmr_accnt_pymnt_amnt) as Mnth_Tot,
--Gives the Month & year (Eg Jul15)
left(datename(Month, cnsmr_accnt_pymnt_pstd_dt), 3) + right(datename(year, cnsmr_accnt_pymnt_pstd_dt), 2) as Month_Yr
from
dbo.cnsmr_accnt_pymnt_jrnl capj
inner join
UDEFGENERAL UG
on
capj.cnsmr_accnt_id = UG.cnsmr_accnt_id
Inner join
wrkgrp w
on
capj.wrkgrp_id = w.wrkgrp_id
where
cnsmr_accnt_pymnt_stts_cd in (5)
and cnsmr_accnt_pymnt_pstd_dt between
--Go back to the 1st day 4 months back
datefromparts(year(dateadd(month, -3, getdate())), month(getdate())-3, 1)
and
getdate()
group by capj.cnsmr_accnt_id,
left(datename(Month, cnsmr_accnt_pymnt_pstd_dt), 3) + right(datename(year, cnsmr_accnt_pymnt_pstd_dt), 2),
wrkgrp_nm) as Mnth_Tot_Tbl
pivot
(
sum(Mnth_Tot)
for
Month_Yr in (@Dates)) as Piv
您需要使用动态 sql 或使用以下内容代替 (@Dates)
中的 Month_Yr
','+@Dates+',' like '%,'+Month_Yr+',%'
如果您想要过去 4 个月的数据,我建议您采用不同的方法,而不是按月和年分组,而是按自本月以来的月数分组。因此,与其尝试动态旋转,不如旋转静态数字 (0, 1, 2, 3);
SELECT *
FROM ( SELECT capj.cnsmr_accnt_id,
wrkgrp_nm,
Instlmnt = MAX(udefinst_amt),
Mnth_Tot = SUM(cnsmr_accnt_pymnt_amnt),
MonthsSinceToday = DATEDIFF(MONTH, cnsmr_accnt_pymnt_pstd_dt, GETDATE())
FROM dbo.cnsmr_accnt_pymnt_jrnl AS capj
INNER JOIN Udefgeneral AS ug
ON capj.cnsmr_accnt_id = ug.cnsmr_accnt_id
INNER JOIN wrkgrp AS w
ON capj.wrkgrp_id = w.wrkgrp_id
WHERE cnsmr_accnt_pymnt_stts_cd IN (5)
AND cnsmr_accnt_pymnt_pstd_dt >= DATEADD(MONTH, DATEDIFF(MONTH, '19000401', GETDATE()), '19000101')
AND cnsmr_accnt_pymnt_pstd_dt < GETDATE()
GROUP BY cnsmr_accnt_id, wrkgrp_nm, DATEDIFF(MONTH, cnsmr_accnt_pymnt_pstd_dt, GETDATE())
) AS d
PIVOT
( SUM(Mnth_Tot)
FOR MonthsSinceToday IN ([0], [1], [2], [3])
) AS pvt;
这种方法的缺点是您的日期不会是列 headers,但优点是您不需要使用动态 sql,并且列名应该很容易无论如何都由您的表示层处理。
First Convert second part into dynamic string and create string query after execute your Query
EXEC('Select *
from
(
Select
capj.cnsmr_accnt_id,
wrkgrp_nm,
max(UDEFINST_AMT) as Instlmnt,
sum(cnsmr_accnt_pymnt_amnt) as Mnth_Tot,
--Gives the Month & year (Eg Jul15)
left(datename(Month, cnsmr_accnt_pymnt_pstd_dt), 3) + right(datename(year, cnsmr_accnt_pymnt_pstd_dt), 2) as Month_Yr
from
dbo.cnsmr_accnt_pymnt_jrnl capj
inner join
UDEFGENERAL UG
on
capj.cnsmr_accnt_id = UG.cnsmr_accnt_id
Inner join
wrkgrp w
on
capj.wrkgrp_id = w.wrkgrp_id
where
cnsmr_accnt_pymnt_stts_cd in (5)
and cnsmr_accnt_pymnt_pstd_dt between
--Go back to the 1st day 4 months back
datefromparts(year(dateadd(month, -3, getdate())), month(getdate())-3, 1)
and
getdate()
group by capj.cnsmr_accnt_id,
left(datename(Month, cnsmr_accnt_pymnt_pstd_dt), 3) + right(datename(year, cnsmr_accnt_pymnt_pstd_dt), 2),
wrkgrp_nm) as Mnth_Tot_Tbl
pivot
(
sum(Mnth_Tot)
for
Month_Yr in (' + @Dates + ')) as Piv')
所以我们有 2 个以上的答案。感谢 GarethD 和 Pradip。
总而言之,我测试了 Pradip 的解决方案如下:
Declare @Dates as nvarchar(max);
--Builds up a string of dates for the last 4 months.
Set @Dates = left(datename(Month, datefromparts(year(dateadd(month, -3, getdate())), month(getdate())-3, 1)), 3) +
right(datename(year, datefromparts(year(dateadd(month, -3, getdate())), month(getdate())-3, 1)), 2) + ',' +
left(datename(Month, datefromparts(year(dateadd(month, -2, getdate())), month(getdate())-2, 1)), 3) +
right(datename(year, datefromparts(year(dateadd(month, -2, getdate())), month(getdate())-2, 1)), 2)+ ',' +
left(datename(Month, datefromparts(year(dateadd(month, -1, getdate())), month(getdate())-1, 1)), 3) +
right(datename(year, datefromparts(year(dateadd(month, -1, getdate())), month(getdate())-1, 1)), 2)+ ',' +
left(datename(Month, getdate()), 3) +
right(datename(year, getdate()), 2);
EXEC('Select *
from
(
Select
capj.cnsmr_accnt_id,
wrkgrp_nm,
max(UDEFINST_AMT) as Instlmnt,
sum(cnsmr_accnt_pymnt_amnt) as Mnth_Tot,
--Gives the Month & year (Eg Jul15)
left(datename(Month, cnsmr_accnt_pymnt_pstd_dt), 3) + right(datename(year, cnsmr_accnt_pymnt_pstd_dt), 2) as Month_Yr
from
dbo.cnsmr_accnt_pymnt_jrnl capj
inner join
UDEFGENERAL UG
on
capj.cnsmr_accnt_id = UG.cnsmr_accnt_id
Inner join
wrkgrp w
on
capj.wrkgrp_id = w.wrkgrp_id
where
cnsmr_accnt_pymnt_stts_cd in (5)
and cnsmr_accnt_pymnt_pstd_dt between
--Go back to the 1st day 4 months back
datefromparts(year(dateadd(month, -3, getdate())), month(getdate())-3, 1)
and
getdate()
group by capj.cnsmr_accnt_id,
left(datename(Month, cnsmr_accnt_pymnt_pstd_dt), 3) + right(datename(year, cnsmr_accnt_pymnt_pstd_dt), 2),
wrkgrp_nm) as Mnth_Tot_Tbl
pivot
(
sum(Mnth_Tot)
for
Month_Yr in (' + @Dates + ')) as Piv')
我每 cnsmr_accnt_id 付款几个月。我希望查看过去 4 个月每月的总付款额。像这样:
Cnsmr_accnt_id | Wrkgrp_nm | Apr15_Tot | May15_Tot | Jun15_Tot | Jul15_Tot 12345 |Workgrp1 | 123424 | 1243255 | 232342 | 23232323 12347 |Workgrp4 | 123323 | 1244455 | 324342 | 232323
我正在尝试使用 Pivot 来执行此操作,但在使用以下代码时一直出现错误。我怀疑这与变量@Dates 范围有关。
@Dates 给我的值是 Apr15、May15、Jun15、Jul15,这是正确的。
如果我将其直接替换为 Select 代替 @Dates,则查询有效。但是当我使用@Dates 时,它会出错。 (“@Dates”附近的语法不正确。)
我也试过将用于设置@Dates 的整个"formula" 放入select 语句中,但这也会出错。 (关键字 'left' 附近的语法不正确)
Declare @Dates as nvarchar(max);
--Builds up a string of dates for the last 4 months.
Set @Dates = left(datename(Month, datefromparts(year(dateadd(month, -3, getdate())), month(getdate())-3, 1)), 3) +
right(datename(year, datefromparts(year(dateadd(month, -3, getdate())), month(getdate())-3, 1)), 2) + ',' +
left(datename(Month, datefromparts(year(dateadd(month, -2, getdate())), month(getdate())-2, 1)), 3) +
right(datename(year, datefromparts(year(dateadd(month, -2, getdate())), month(getdate())-2, 1)), 2)+ ',' +
left(datename(Month, datefromparts(year(dateadd(month, -1, getdate())), month(getdate())-1, 1)), 3) +
right(datename(year, datefromparts(year(dateadd(month, -1, getdate())), month(getdate())-1, 1)), 2)+ ',' +
left(datename(Month, getdate()), 3) +
right(datename(year, getdate()), 2);
--Print @dates
--Example output = Apr15,May15,Jun15,Jul15
--Use a pivot to get the totals per cnsmr_accnt_id for the last 4 months.
Select *
from
(
Select
capj.cnsmr_accnt_id,
wrkgrp_nm,
max(UDEFINST_AMT) as Instlmnt,
sum(cnsmr_accnt_pymnt_amnt) as Mnth_Tot,
--Gives the Month & year (Eg Jul15)
left(datename(Month, cnsmr_accnt_pymnt_pstd_dt), 3) + right(datename(year, cnsmr_accnt_pymnt_pstd_dt), 2) as Month_Yr
from
dbo.cnsmr_accnt_pymnt_jrnl capj
inner join
UDEFGENERAL UG
on
capj.cnsmr_accnt_id = UG.cnsmr_accnt_id
Inner join
wrkgrp w
on
capj.wrkgrp_id = w.wrkgrp_id
where
cnsmr_accnt_pymnt_stts_cd in (5)
and cnsmr_accnt_pymnt_pstd_dt between
--Go back to the 1st day 4 months back
datefromparts(year(dateadd(month, -3, getdate())), month(getdate())-3, 1)
and
getdate()
group by capj.cnsmr_accnt_id,
left(datename(Month, cnsmr_accnt_pymnt_pstd_dt), 3) + right(datename(year, cnsmr_accnt_pymnt_pstd_dt), 2),
wrkgrp_nm) as Mnth_Tot_Tbl
pivot
(
sum(Mnth_Tot)
for
Month_Yr in (@Dates)) as Piv
您需要使用动态 sql 或使用以下内容代替 (@Dates)
中的 Month_Yr','+@Dates+',' like '%,'+Month_Yr+',%'
如果您想要过去 4 个月的数据,我建议您采用不同的方法,而不是按月和年分组,而是按自本月以来的月数分组。因此,与其尝试动态旋转,不如旋转静态数字 (0, 1, 2, 3);
SELECT *
FROM ( SELECT capj.cnsmr_accnt_id,
wrkgrp_nm,
Instlmnt = MAX(udefinst_amt),
Mnth_Tot = SUM(cnsmr_accnt_pymnt_amnt),
MonthsSinceToday = DATEDIFF(MONTH, cnsmr_accnt_pymnt_pstd_dt, GETDATE())
FROM dbo.cnsmr_accnt_pymnt_jrnl AS capj
INNER JOIN Udefgeneral AS ug
ON capj.cnsmr_accnt_id = ug.cnsmr_accnt_id
INNER JOIN wrkgrp AS w
ON capj.wrkgrp_id = w.wrkgrp_id
WHERE cnsmr_accnt_pymnt_stts_cd IN (5)
AND cnsmr_accnt_pymnt_pstd_dt >= DATEADD(MONTH, DATEDIFF(MONTH, '19000401', GETDATE()), '19000101')
AND cnsmr_accnt_pymnt_pstd_dt < GETDATE()
GROUP BY cnsmr_accnt_id, wrkgrp_nm, DATEDIFF(MONTH, cnsmr_accnt_pymnt_pstd_dt, GETDATE())
) AS d
PIVOT
( SUM(Mnth_Tot)
FOR MonthsSinceToday IN ([0], [1], [2], [3])
) AS pvt;
这种方法的缺点是您的日期不会是列 headers,但优点是您不需要使用动态 sql,并且列名应该很容易无论如何都由您的表示层处理。
First Convert second part into dynamic string and create string query after execute your Query EXEC('Select * from ( Select capj.cnsmr_accnt_id, wrkgrp_nm, max(UDEFINST_AMT) as Instlmnt, sum(cnsmr_accnt_pymnt_amnt) as Mnth_Tot, --Gives the Month & year (Eg Jul15) left(datename(Month, cnsmr_accnt_pymnt_pstd_dt), 3) + right(datename(year, cnsmr_accnt_pymnt_pstd_dt), 2) as Month_Yr from dbo.cnsmr_accnt_pymnt_jrnl capj inner join UDEFGENERAL UG on capj.cnsmr_accnt_id = UG.cnsmr_accnt_id Inner join wrkgrp w on capj.wrkgrp_id = w.wrkgrp_id where cnsmr_accnt_pymnt_stts_cd in (5) and cnsmr_accnt_pymnt_pstd_dt between --Go back to the 1st day 4 months back datefromparts(year(dateadd(month, -3, getdate())), month(getdate())-3, 1) and getdate() group by capj.cnsmr_accnt_id, left(datename(Month, cnsmr_accnt_pymnt_pstd_dt), 3) + right(datename(year, cnsmr_accnt_pymnt_pstd_dt), 2), wrkgrp_nm) as Mnth_Tot_Tbl pivot ( sum(Mnth_Tot) for Month_Yr in (' + @Dates + ')) as Piv')
所以我们有 2 个以上的答案。感谢 GarethD 和 Pradip。
总而言之,我测试了 Pradip 的解决方案如下:
Declare @Dates as nvarchar(max);
--Builds up a string of dates for the last 4 months.
Set @Dates = left(datename(Month, datefromparts(year(dateadd(month, -3, getdate())), month(getdate())-3, 1)), 3) +
right(datename(year, datefromparts(year(dateadd(month, -3, getdate())), month(getdate())-3, 1)), 2) + ',' +
left(datename(Month, datefromparts(year(dateadd(month, -2, getdate())), month(getdate())-2, 1)), 3) +
right(datename(year, datefromparts(year(dateadd(month, -2, getdate())), month(getdate())-2, 1)), 2)+ ',' +
left(datename(Month, datefromparts(year(dateadd(month, -1, getdate())), month(getdate())-1, 1)), 3) +
right(datename(year, datefromparts(year(dateadd(month, -1, getdate())), month(getdate())-1, 1)), 2)+ ',' +
left(datename(Month, getdate()), 3) +
right(datename(year, getdate()), 2);
EXEC('Select *
from
(
Select
capj.cnsmr_accnt_id,
wrkgrp_nm,
max(UDEFINST_AMT) as Instlmnt,
sum(cnsmr_accnt_pymnt_amnt) as Mnth_Tot,
--Gives the Month & year (Eg Jul15)
left(datename(Month, cnsmr_accnt_pymnt_pstd_dt), 3) + right(datename(year, cnsmr_accnt_pymnt_pstd_dt), 2) as Month_Yr
from
dbo.cnsmr_accnt_pymnt_jrnl capj
inner join
UDEFGENERAL UG
on
capj.cnsmr_accnt_id = UG.cnsmr_accnt_id
Inner join
wrkgrp w
on
capj.wrkgrp_id = w.wrkgrp_id
where
cnsmr_accnt_pymnt_stts_cd in (5)
and cnsmr_accnt_pymnt_pstd_dt between
--Go back to the 1st day 4 months back
datefromparts(year(dateadd(month, -3, getdate())), month(getdate())-3, 1)
and
getdate()
group by capj.cnsmr_accnt_id,
left(datename(Month, cnsmr_accnt_pymnt_pstd_dt), 3) + right(datename(year, cnsmr_accnt_pymnt_pstd_dt), 2),
wrkgrp_nm) as Mnth_Tot_Tbl
pivot
(
sum(Mnth_Tot)
for
Month_Yr in (' + @Dates + ')) as Piv')