在案例中使用汇总方法的视图中创建列...表达式

问题描述

我正在尝试在SQL Server中创建一个视图,该视图呈现3个表中的列并创建4个NEW列。这些新列使用SQL“ Case ... When”语法根据同一表中相邻列[Portfolio Report Category]的值有条件地呈现现有字段的SUM。

目标是显示4个不同资产类别的单个帐户的总市值。现在,一个[帐号]可以有一个[投资组合报告类别]多个记录,其中[投资金额]。因此,很明显,此视图应允许[帐号]仅有一个记录,且该记录具有4个满足“ Case ... When”条件的总货币值。

我已经读过类似的线程,但是没有一个在条件块中的“ Then”关键字之后解决聚合方法。当我将Sum()放在“ Case”之前,并在“ Then”之后删除它时,没有错误,但计算错误:在许多情况下,它们要高得多。我的印象是,简单的Try_Convert到钱就足够了,确实,如果我执行SUM(Try_Convert(money,[Market_Value])其中[Account Number] ='x',结果是正确的。 m创建视图。

以下是使用SELECT测试以下代码时的错误:

选择列表中的“ KTHoldings.Portfolio报告类别”列无效,因为它既不包含在聚合函数中,也不包含在GROUP BY子句中。

下面是KTHoldings表,该表返回单个帐户的所有记录。我基本上需要视图的[其他总价值]列来汇总其[市场价值]数据。

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','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],ktc.[Available Cash Amount]
)

KTAccountsADR表

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表

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表

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,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','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],ktc.[Available Cash Amount];

哪个返回(删除了不必要的列):

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表中有多行。解决重复项,在case中使用sum时,您将获得正确的值。

请注意,其最佳做法是确保您从case表达式的所有分支返回相同的数据类型。

相关问答

依赖报错 idea导入项目后依赖报错,解决方案:https://blog....
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下...
错误1:gradle项目控制台输出为乱码 # 解决方案:https://bl...
错误还原:在查询的过程中,传入的workType为0时,该条件不起...
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct...