在案例中使用聚合方法的视图中创建列...当表达式
Creating Columns in a View That Use an Aggregate Method in a Case...When Expression
我正在尝试在 SQL 服务器中创建一个视图,该视图呈现来自 3 table 的列并创建 4 个新列。这些新列使用 SQL“Case...When”语法根据同一 table 中相邻列 [Portfolio Report Category] 的值有条件地呈现现有字段的 SUM。
objective 是显示单个账户 4 种不同资产类别的总市值。现在,对于单个 [投资组合报告类别],一个 [帐号] 可以有许多记录和许多 [投资金额]。所以很明显,这个视图应该允许 [Account Number] 只有一个记录,其中包含 4 个满足“Case...When”条件的总货币值。
我读过类似的线程,但是 none 它在条件块中的“Then”关键字之后解决了聚合方法。当我将 Sum() 放在“Case”之前并在“Then”之后将其删除时,没有错误,但计算是错误的:在许多情况下,它们要高得多。我的印象是简单的 Try_Convert 到 money 就足够了,实际上如果我执行 SUM(Try_Convert(money, [Market_Value]) Where [Account Number] = 'x',结果是正确的。但是当我创建视图时不是。
下面是使用SELECT测试以下代码时的错误:
Column 'KTHoldings.Portfolio Report Category' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause.
下面是 KTHoldings table 返回单个帐户的所有记录。我基本上需要我视图的 [Other Total Value] 列来汇总其 [Market Value] 数据。
CREATE VIEW VW_KTAccountsADR AS (
SELECT adr.[Account Number], adr.[Account_ Display Name], adr.[Account Category Code], adr.[Division Code], adr.[Division Name], adr.[Market Value Amount],
CASE WHEN kth.[Portfolio Report Category] = '705' THEN SUM((TRY_CONVERT(money, kth.[Market Value]))) ELSE '0.00' END AS [Crypto Total Value],
CASE WHEN kth.[Portfolio Report Category] = '691' THEN SUM((TRY_CONVERT(money, kth.[Market Value]))) ELSE '0.00' END AS [Precious Metal Total Value],
CASE WHEN kth.[Portfolio Report Category] IN ('010', '011', '020', '025', '030') THEN SUM((TRY_CONVERT(money, kth.[Market Value]))) ELSE '0.00' END AS [Stock Total Value],
CASE WHEN kth.[Portfolio Report Category] NOT IN ('010', '011', '020', '025', '030', '691', '705') THEN SUM((TRY_CONVERT(money, kth.[Market Value]))) ELSE '0.00' END AS [Other Total Value],
ktc.[Available Cash Amount] AS [CASH TOTAL]
FROM KTAccountsADR adr
INNER JOIN KTHoldings kth
ON adr.[Account Number] = kth.[Account Number]
INNER JOIN KTCash ktc
ON adr.[Account Number] = ktc.[Account Number]
GROUP BY adr.[Account Number], adr.[Account_ Display Name], adr.[Account Category Code], adr.[Division Code], adr.[Division Code], adr.[Division Name], adr.[Market Value Amount], ktc.[Available Cash Amount]
)
KTAccountsADR Table
Account Number Display Name Division Code Market Value Amount
07007835 Frank C Thomas Roth IRA 27 390410.98
07007835 Frank C Thomas Roth IRA 27 390410.98
07007835 Frank C Thomas Roth IRA 27 390410.98
07007835 Frank C Thomas Roth IRA 27 390410.98
001000 Carl S Sykes Roth IRA 27 196338.1292
001000 Carl S Sykes Roth IRA 27 196338.1292
001000 Carl S Sykes Roth IRA 27 196338.1292
KTHoldings Table
Account Number Display Name Market Value Portfolio Report Category
001000 Carl S Sykes Roth IRA 9998.4792 600
001000 Carl S Sykes Roth IRA 43467.09 600
001000 Carl S Sykes Roth IRA 84524.71 600
KTCash Table
Account Number Available Cash Amount
001000 58347.85
您需要将 case
放入 sum
:
SUM(CASE WHEN kth.[Portfolio Report Category] = '705' THEN TRY_CONVERT(money, kth.[Market Value]) ELSE '0.00' END) AS [Crypto Total Value],
这是一个工作示例:
declare @Adr table ([Account Number] varchar(6), [Account_ Display Name] varchar(64), [Account Category Code] varchar, [Division Code] varchar, [Division Name] varchar, [Market Value Amount] money);
declare @Kth table ([Account Number] varchar(6), [Portfolio Report Category] varchar(3), [Market Value] money);
declare @Ktc table ([Account Number] varchar(6), [Available Cash Amount] money);
insert into @Adr ([Account Number], [Account_ Display Name])
values ('001000', 'Carl S Sykes Roth IRA');
insert into @Kth ([Account Number], [Market Value], [Portfolio Report Category])
values ('001000', 9998.4792, '600'),
('001000', 43467.09, '600'),
('001000', 84524.71, '600');
insert into @Ktc ([Account Number])
values ('001000');
SELECT adr.[Account Number], adr.[Account_ Display Name], adr.[Account Category Code], adr.[Division Code], adr.[Division Name], adr.[Market Value Amount]
, SUM(CASE WHEN kth.[Portfolio Report Category] = '705' THEN (TRY_CONVERT(money, kth.[Market Value])) ELSE 0 END) AS [Crypto Total Value]
, SUM(CASE WHEN kth.[Portfolio Report Category] = '691' THEN (TRY_CONVERT(money, kth.[Market Value])) ELSE 0 END) AS [Precious Metal Total Value]
, SUM(CASE WHEN kth.[Portfolio Report Category] IN ('010', '011', '020', '025', '030') THEN (TRY_CONVERT(money, kth.[Market Value])) ELSE 0 END) AS [Stock Total Value]
, SUM(CASE WHEN kth.[Portfolio Report Category] NOT IN ('010', '011', '020', '025', '030', '691', '705') THEN (TRY_CONVERT(money, kth.[Market Value])) ELSE 0 END) AS [Other Total Value]
, ktc.[Available Cash Amount] AS [CASH TOTAL]
FROM @Adr adr
INNER JOIN @Kth kth ON adr.[Account Number] = kth.[Account Number]
INNER JOIN @Ktc ktc ON adr.[Account Number] = ktc.[Account Number]
GROUP BY adr.[Account Number], adr.[Account_ Display Name], adr.[Account Category Code], adr.[Division Code], adr.[Division Code], adr.[Division Name], adr.[Market Value Amount], ktc.[Available Cash Amount];
returns(删除了 un-necessary 列):
Account Number Crypto Total Value Precious Metal Total Value Stock Total Value Other Total Value CASH TOTAL
001000 0.00 0.00 0.00 137990.2792 NULL
编辑:由于您现在已经添加了示例数据,所以您得到不正确值的原因是因为您在 KTAccountsADR
中有重复的行,然后在 KTHoldings
[=32] 中有多个行=].解决重复项,在 sum
.
中使用 case
时,您将获得正确的值
请注意,确保从 case
表达式的所有分支返回相同数据类型的最佳做法。
我正在尝试在 SQL 服务器中创建一个视图,该视图呈现来自 3 table 的列并创建 4 个新列。这些新列使用 SQL“Case...When”语法根据同一 table 中相邻列 [Portfolio Report Category] 的值有条件地呈现现有字段的 SUM。
objective 是显示单个账户 4 种不同资产类别的总市值。现在,对于单个 [投资组合报告类别],一个 [帐号] 可以有许多记录和许多 [投资金额]。所以很明显,这个视图应该允许 [Account Number] 只有一个记录,其中包含 4 个满足“Case...When”条件的总货币值。
我读过类似的线程,但是 none 它在条件块中的“Then”关键字之后解决了聚合方法。当我将 Sum() 放在“Case”之前并在“Then”之后将其删除时,没有错误,但计算是错误的:在许多情况下,它们要高得多。我的印象是简单的 Try_Convert 到 money 就足够了,实际上如果我执行 SUM(Try_Convert(money, [Market_Value]) Where [Account Number] = 'x',结果是正确的。但是当我创建视图时不是。
下面是使用SELECT测试以下代码时的错误:
Column 'KTHoldings.Portfolio Report Category' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause.
下面是 KTHoldings table 返回单个帐户的所有记录。我基本上需要我视图的 [Other Total Value] 列来汇总其 [Market Value] 数据。
CREATE VIEW VW_KTAccountsADR AS (
SELECT adr.[Account Number], adr.[Account_ Display Name], adr.[Account Category Code], adr.[Division Code], adr.[Division Name], adr.[Market Value Amount],
CASE WHEN kth.[Portfolio Report Category] = '705' THEN SUM((TRY_CONVERT(money, kth.[Market Value]))) ELSE '0.00' END AS [Crypto Total Value],
CASE WHEN kth.[Portfolio Report Category] = '691' THEN SUM((TRY_CONVERT(money, kth.[Market Value]))) ELSE '0.00' END AS [Precious Metal Total Value],
CASE WHEN kth.[Portfolio Report Category] IN ('010', '011', '020', '025', '030') THEN SUM((TRY_CONVERT(money, kth.[Market Value]))) ELSE '0.00' END AS [Stock Total Value],
CASE WHEN kth.[Portfolio Report Category] NOT IN ('010', '011', '020', '025', '030', '691', '705') THEN SUM((TRY_CONVERT(money, kth.[Market Value]))) ELSE '0.00' END AS [Other Total Value],
ktc.[Available Cash Amount] AS [CASH TOTAL]
FROM KTAccountsADR adr
INNER JOIN KTHoldings kth
ON adr.[Account Number] = kth.[Account Number]
INNER JOIN KTCash ktc
ON adr.[Account Number] = ktc.[Account Number]
GROUP BY adr.[Account Number], adr.[Account_ Display Name], adr.[Account Category Code], adr.[Division Code], adr.[Division Code], adr.[Division Name], adr.[Market Value Amount], ktc.[Available Cash Amount]
)
KTAccountsADR Table
Account Number Display Name Division Code Market Value Amount
07007835 Frank C Thomas Roth IRA 27 390410.98
07007835 Frank C Thomas Roth IRA 27 390410.98
07007835 Frank C Thomas Roth IRA 27 390410.98
07007835 Frank C Thomas Roth IRA 27 390410.98
001000 Carl S Sykes Roth IRA 27 196338.1292
001000 Carl S Sykes Roth IRA 27 196338.1292
001000 Carl S Sykes Roth IRA 27 196338.1292
KTHoldings Table
Account Number Display Name Market Value Portfolio Report Category
001000 Carl S Sykes Roth IRA 9998.4792 600
001000 Carl S Sykes Roth IRA 43467.09 600
001000 Carl S Sykes Roth IRA 84524.71 600
KTCash Table
Account Number Available Cash Amount
001000 58347.85
您需要将 case
放入 sum
:
SUM(CASE WHEN kth.[Portfolio Report Category] = '705' THEN TRY_CONVERT(money, kth.[Market Value]) ELSE '0.00' END) AS [Crypto Total Value],
这是一个工作示例:
declare @Adr table ([Account Number] varchar(6), [Account_ Display Name] varchar(64), [Account Category Code] varchar, [Division Code] varchar, [Division Name] varchar, [Market Value Amount] money);
declare @Kth table ([Account Number] varchar(6), [Portfolio Report Category] varchar(3), [Market Value] money);
declare @Ktc table ([Account Number] varchar(6), [Available Cash Amount] money);
insert into @Adr ([Account Number], [Account_ Display Name])
values ('001000', 'Carl S Sykes Roth IRA');
insert into @Kth ([Account Number], [Market Value], [Portfolio Report Category])
values ('001000', 9998.4792, '600'),
('001000', 43467.09, '600'),
('001000', 84524.71, '600');
insert into @Ktc ([Account Number])
values ('001000');
SELECT adr.[Account Number], adr.[Account_ Display Name], adr.[Account Category Code], adr.[Division Code], adr.[Division Name], adr.[Market Value Amount]
, SUM(CASE WHEN kth.[Portfolio Report Category] = '705' THEN (TRY_CONVERT(money, kth.[Market Value])) ELSE 0 END) AS [Crypto Total Value]
, SUM(CASE WHEN kth.[Portfolio Report Category] = '691' THEN (TRY_CONVERT(money, kth.[Market Value])) ELSE 0 END) AS [Precious Metal Total Value]
, SUM(CASE WHEN kth.[Portfolio Report Category] IN ('010', '011', '020', '025', '030') THEN (TRY_CONVERT(money, kth.[Market Value])) ELSE 0 END) AS [Stock Total Value]
, SUM(CASE WHEN kth.[Portfolio Report Category] NOT IN ('010', '011', '020', '025', '030', '691', '705') THEN (TRY_CONVERT(money, kth.[Market Value])) ELSE 0 END) AS [Other Total Value]
, ktc.[Available Cash Amount] AS [CASH TOTAL]
FROM @Adr adr
INNER JOIN @Kth kth ON adr.[Account Number] = kth.[Account Number]
INNER JOIN @Ktc ktc ON adr.[Account Number] = ktc.[Account Number]
GROUP BY adr.[Account Number], adr.[Account_ Display Name], adr.[Account Category Code], adr.[Division Code], adr.[Division Code], adr.[Division Name], adr.[Market Value Amount], ktc.[Available Cash Amount];
returns(删除了 un-necessary 列):
Account Number Crypto Total Value Precious Metal Total Value Stock Total Value Other Total Value CASH TOTAL
001000 0.00 0.00 0.00 137990.2792 NULL
编辑:由于您现在已经添加了示例数据,所以您得到不正确值的原因是因为您在 KTAccountsADR
中有重复的行,然后在 KTHoldings
[=32] 中有多个行=].解决重复项,在 sum
.
case
时,您将获得正确的值
请注意,确保从 case
表达式的所有分支返回相同数据类型的最佳做法。