Sql 返回在另一个定义了要求和的科目或范围的表中指定的科目总和的查询
我有一个用户正在维护的表格,在那里他们可以使用“统计帐户”定义他们想要汇总的帐户-无论是指定帐户还是范围帐户。您如何构建一个视图,以最好地汇总pr stat帐户和月份的金额。我需要以某种方式使pr.account能够更改where子句 下面我有两个表:DimStatAccount和FactAmount,下面是预期的视图Sql 返回在另一个定义了要求和的科目或范围的表中指定的科目总和的查询,sql,tsql,sql-server-2016,Sql,Tsql,Sql Server 2016,我有一个用户正在维护的表格,在那里他们可以使用“统计帐户”定义他们想要汇总的帐户-无论是指定帐户还是范围帐户。您如何构建一个视图,以最好地汇总pr stat帐户和月份的金额。我需要以某种方式使pr.account能够更改where子句 下面我有两个表:DimStatAccount和FactAmount,下面是预期的视图 正如前面所说,动态sql是您所需要的 CREATE TABLE #dimStatAccount (StatAccount varchar(255), Accounts varch
正如前面所说,动态sql是您所需要的
CREATE TABLE #dimStatAccount (StatAccount varchar(255), Accounts varchar(255), AccountsRange varchar(255))
INSERT INTO #dimStatAccount VALUES
('Stat1', 'in (1000,1020)', null),
('Stat2', 'in (1020,2020)', null),
('Stat3', null, 'between 1000 and 1999'),
('Stat4', null, 'between 2000 and 2999')
CREATE TABLE #factAmount (Account int, [Month] varchar(255), Amount int)
INSERT INTO #factAmount VALUES
(1000,'jan',500),
(1000,'feb',460),
(1010,'jan',799),
(1010,'jan',855),
(1010,'feb',633),
(1020,'feb',522),
(2000,'jan',436),
(2000,'jan',946),
(2000,'jan',374),
(2010,'jan',683),
(2010,'feb',492),
(2020,'jan',437),
(2020,'feb',834),
(2030,'jan',944)
CREATE TABLE #result (StatAccount varchar(255), [Month] varchar(255), SumAmount int)
DECLARE @statAccount varchar(255), @accounts varchar(255), @rangeAccounts varchar(255)
DECLARE rcursor CURSOR FOR
SELECT StatAccount, Accounts, AccountsRange
FROM #dimStatAccount
OPEN rcursor
FETCH NEXT FROM rcursor
INTO @statAccount, @accounts, @rangeAccounts
WHILE @@FETCH_STATUS = 0
BEGIN
DECLARE @sql NVARCHAR(max)
IF @accounts IS NOT NULL
BEGIN
SET @Sql = 'INSERT INTO #result '
SET @sql = @Sql + 'SELECT ''' + @statAccount + ''' AS StatAccount, [MONTH], SUM(f.Amount) AS SumAmount '
SET @Sql = @Sql + 'FROM #factAmount AS f '
SET @Sql = @Sql + 'WHERE Account ' + @accounts + ' '
SET @Sql = @Sql + 'GROUP BY [Month]'
EXEC sp_executesql @Sql
FETCH NEXT FROM rcursor
INTO @statAccount, @accounts, @rangeAccounts
END
IF @rangeAccounts IS NOT NULL
BEGIN
SET @Sql = 'INSERT INTO #result '
SET @sql = @Sql + 'SELECT ''' + @statAccount + ''' AS StatAccount, [MONTH], SUM(f.Amount) AS SumAmount '
SET @Sql = @Sql + 'FROM #factAmount AS f '
SET @Sql = @Sql + 'WHERE Account ' + @rangeAccounts + ' '
SET @Sql = @Sql + 'GROUP BY [Month]'
print @Sql
EXEC sp_executesql @Sql
FETCH NEXT FROM rcursor
INTO @statAccount, @accounts, @rangeAccounts
END
END
CLOSE rcursor
DEALLOCATE rcursor
SELECT * FROM #result
结果
StatAccount Month SumAmount
-----------------------------
Stat1 feb 982
Stat1 jan 500
Stat2 feb 1356
Stat2 jan 437
Stat3 feb 1615
Stat3 jan 2154
Stat4 feb 1326
Stat4 jan 3820
如前所述,动态sql是您所需要的
CREATE TABLE #dimStatAccount (StatAccount varchar(255), Accounts varchar(255), AccountsRange varchar(255))
INSERT INTO #dimStatAccount VALUES
('Stat1', 'in (1000,1020)', null),
('Stat2', 'in (1020,2020)', null),
('Stat3', null, 'between 1000 and 1999'),
('Stat4', null, 'between 2000 and 2999')
CREATE TABLE #factAmount (Account int, [Month] varchar(255), Amount int)
INSERT INTO #factAmount VALUES
(1000,'jan',500),
(1000,'feb',460),
(1010,'jan',799),
(1010,'jan',855),
(1010,'feb',633),
(1020,'feb',522),
(2000,'jan',436),
(2000,'jan',946),
(2000,'jan',374),
(2010,'jan',683),
(2010,'feb',492),
(2020,'jan',437),
(2020,'feb',834),
(2030,'jan',944)
CREATE TABLE #result (StatAccount varchar(255), [Month] varchar(255), SumAmount int)
DECLARE @statAccount varchar(255), @accounts varchar(255), @rangeAccounts varchar(255)
DECLARE rcursor CURSOR FOR
SELECT StatAccount, Accounts, AccountsRange
FROM #dimStatAccount
OPEN rcursor
FETCH NEXT FROM rcursor
INTO @statAccount, @accounts, @rangeAccounts
WHILE @@FETCH_STATUS = 0
BEGIN
DECLARE @sql NVARCHAR(max)
IF @accounts IS NOT NULL
BEGIN
SET @Sql = 'INSERT INTO #result '
SET @sql = @Sql + 'SELECT ''' + @statAccount + ''' AS StatAccount, [MONTH], SUM(f.Amount) AS SumAmount '
SET @Sql = @Sql + 'FROM #factAmount AS f '
SET @Sql = @Sql + 'WHERE Account ' + @accounts + ' '
SET @Sql = @Sql + 'GROUP BY [Month]'
EXEC sp_executesql @Sql
FETCH NEXT FROM rcursor
INTO @statAccount, @accounts, @rangeAccounts
END
IF @rangeAccounts IS NOT NULL
BEGIN
SET @Sql = 'INSERT INTO #result '
SET @sql = @Sql + 'SELECT ''' + @statAccount + ''' AS StatAccount, [MONTH], SUM(f.Amount) AS SumAmount '
SET @Sql = @Sql + 'FROM #factAmount AS f '
SET @Sql = @Sql + 'WHERE Account ' + @rangeAccounts + ' '
SET @Sql = @Sql + 'GROUP BY [Month]'
print @Sql
EXEC sp_executesql @Sql
FETCH NEXT FROM rcursor
INTO @statAccount, @accounts, @rangeAccounts
END
END
CLOSE rcursor
DEALLOCATE rcursor
SELECT * FROM #result
结果
StatAccount Month SumAmount
-----------------------------
Stat1 feb 982
Stat1 jan 500
Stat2 feb 1356
Stat2 jan 437
Stat3 feb 1615
Stat3 jan 2154
Stat4 feb 1326
Stat4 jan 3820
我从凯文的回答中偷了一桌子东西。可以使用select into变量功能从DimStatAccount表创建动态SQL select语句
CREATE TABLE DimStatAccount (StatAccount varchar(255), Accounts varchar(255), AccountsRange varchar(255))
INSERT INTO DimStatAccount VALUES
('Stat1', 'in (1000,1020)', null),
('Stat2', 'in (1020,2020)', null),
('Stat3', null, 'between 1000 and 1999'),
('Stat4', null, 'between 2000 and 2999')
CREATE TABLE FactAmount (Account int, [Month] varchar(255), Amount int)
INSERT INTO FactAmount VALUES
(1000,'jan',500),
(1000,'feb',460),
(1010,'jan',799),
(1010,'jan',855),
(1010,'feb',633),
(1020,'feb',522),
(2000,'jan',436),
(2000,'jan',946),
(2000,'jan',374),
(2010,'jan',683),
(2010,'feb',492),
(2020,'jan',437),
(2020,'feb',834),
(2030,'jan',944)
DECLARE @sqlStatement NVARCHAR(MAX) = '';
SELECT @sqlStatement += CONCAT('SELECT ''',StatAccount,''',[Month],SUM(Amount) FROM FactAmount WHERE Account ',ISNULL(Accounts,AccountsRange),' GROUP BY [Month] UNION ALL ')
FROM DimStatAccount
;
SET @sqlStatement = LEFT(@sqlStatement,LEN(@sqlStatement)-10); --remove the final Union All
EXEC sp_executesql @sqlStatement;
我从凯文的回答中偷了一桌子东西。可以使用select into变量功能从DimStatAccount表创建动态SQL select语句
CREATE TABLE DimStatAccount (StatAccount varchar(255), Accounts varchar(255), AccountsRange varchar(255))
INSERT INTO DimStatAccount VALUES
('Stat1', 'in (1000,1020)', null),
('Stat2', 'in (1020,2020)', null),
('Stat3', null, 'between 1000 and 1999'),
('Stat4', null, 'between 2000 and 2999')
CREATE TABLE FactAmount (Account int, [Month] varchar(255), Amount int)
INSERT INTO FactAmount VALUES
(1000,'jan',500),
(1000,'feb',460),
(1010,'jan',799),
(1010,'jan',855),
(1010,'feb',633),
(1020,'feb',522),
(2000,'jan',436),
(2000,'jan',946),
(2000,'jan',374),
(2010,'jan',683),
(2010,'feb',492),
(2020,'jan',437),
(2020,'feb',834),
(2030,'jan',944)
DECLARE @sqlStatement NVARCHAR(MAX) = '';
SELECT @sqlStatement += CONCAT('SELECT ''',StatAccount,''',[Month],SUM(Amount) FROM FactAmount WHERE Account ',ISNULL(Accounts,AccountsRange),' GROUP BY [Month] UNION ALL ')
FROM DimStatAccount
;
SET @sqlStatement = LEFT(@sqlStatement,LEN(@sqlStatement)-10); --remove the final Union All
EXEC sp_executesql @sqlStatement;
你试过什么?有研究吗?这些表有模式吗?提示:使用适当的软件(MySQL、Oracle、DB2等)和版本(例如,
sql-server-2014
)标记数据库问题很有帮助。语法和功能的差异通常会影响答案。似乎您希望使用动态SQL。我同意@xQbert的观点,使用动态SQL的存储过程将非常简单。只需确保对帐户和帐户范围的输入进行了良好的清理。这是@xQbert的一个好观点,如果没有正确填充,我的答案肯定会分崩离析。我还使用了CONCAT(),它假设SQL Server 2012或更高版本,但是如果使用早期版本,您可以调整为ISNULL()和+连接。您尝试了什么?有研究吗?这些表有模式吗?提示:使用适当的软件(MySQL、Oracle、DB2等)和版本(例如,sql-server-2014
)标记数据库问题很有帮助。语法和功能的差异通常会影响答案。似乎您希望使用动态SQL。我同意@xQbert的观点,使用动态SQL的存储过程将非常简单。只需确保对帐户和帐户范围的输入进行了良好的清理。这是@xQbert的一个好观点,如果没有正确填充,我的答案肯定会分崩离析。我还使用了CONCAT(),它假定SQL Server 2012或更高版本,但是如果使用早期版本,您可以调整为ISNULL()和+连接。感谢您将插入内容写入原始表,我讨厌这样做。但是,不需要游标或临时表;一个简单的动态SQL选择将解决这个问题感谢您将插入写入原始表,我讨厌这样做。但是,不需要游标或临时表;一个简单的动态SQL选择将解决这个问题,比我的问题要简单得多。美好的我会记住这一点。谢谢,唯一的问题是能够有一个可以返回此结果的视图。我想不可能创建一个执行存储过程的视图?您可以创建一个视图,但您的问题是每次更新维度表时,它都必须更改。因此,在最坏的情况下,只要表发生更改,您就可以触发该表重新创建视图。这比我的要简单得多。美好的我会记住这一点。谢谢,唯一的问题是能够有一个可以返回此结果的视图。我想不可能创建一个执行存储过程的视图?您可以创建一个视图,但您的问题是每次更新维度表时,它都必须更改。因此,在最坏的情况下,只要表发生更改,就可以触发该表重新创建视图。