Sql 必须计算公式列并显示结果
表输入Sql 必须计算公式列并显示结果,sql,sql-server,sql-server-2012,Sql,Sql Server,Sql Server 2012,表输入 IF OBJECT_ID('TEMPDB..#t1') IS NOT NULL DROP TABLE #t1 CREATE TABLE #t1 ([a] int, [b] int, [c] varchar(100)) ; INSERT INTO #t1 ([a], [b], [c]) VALUES (1, 2, 'a+b'), (5, 6, 'a*b'), (2, 1, 'a-b'), (3, 8, 'b/a') ; select *
IF OBJECT_ID('TEMPDB..#t1') IS NOT NULL
DROP TABLE #t1
CREATE TABLE #t1
([a] int, [b] int, [c] varchar(100))
;
INSERT INTO #t1
([a], [b], [c])
VALUES
(1, 2, 'a+b'),
(5, 6, 'a*b'),
(2, 1, 'a-b'),
(3, 8, 'b/a')
;
select * from #t1
表格的结果
预期产量
预期结果如上所示。
在一个表中,我们有一些列和每个记录的公式,我们需要显示所有列,但在公式列而不是公式中,我们需要显示基于公式列c的计算结果
注意:我们需要它是动态的,我们不知道使用公式列需要什么公式。公式不能是静态的,因为没有太多选项
SELECT a, b, CASE
WHEN c = 'a+b' or c = 'b+a' THEN a + b
WHEN c = 'a-b' THEN a - b
WHEN c = 'a*b' or c = 'b*a' THEN a * b
WHEN c = 'a/b' THEN a / b
WHEN c = 'b-a' THEN b - a
WHEN c = 'b/a' THEN b / a
END c
FROM #t1
您可以使用游标来获得更通用的解决方案
DECLARE c CURSOR FOR SELECT a, b, c FROM #t1;
DECLARE @v varchar(100)
DECLARE @a int
DECLARE @b int
DECLARE @sqlcmd varchar(8000)
OPEN c
FETCH NEXT FROM c INTO @a, @b, @v
SET @sqlcmd = 'SELECT ' + @v + ' FROM (SELECT CAST(' + CAST(@a as varchar) + ' AS DECIMAL(10,2)) as a, CAST(' + CAST(@b as varchar) + ' AS DECIMAL(10,2)) as b) t'
WHILE @@FETCH_STATUS = 0
BEGIN
FETCH NEXT FROM c INTO @a, @b, @v
IF (@@FETCH_STATUS <> 0) BREAK;
SET @sqlcmd = @sqlcmd + (' UNION ALL SELECT ' + @v + ' FROM (SELECT CAST(' + CAST(@a as varchar) + ' AS DECIMAL(10,2)) as a, CAST(' + CAST(@b as varchar) + ' AS DECIMAL(10,2)) as b) t')
END
PRINT @sqlcmd
EXEC (@sqlcmd)
CLOSE c
DEALLOCATE c
下面是一种使用动态sql执行公式的简单方法:
CREATE TABLE #t1
(
[a] INT,
[b] INT,
[c] VARCHAR(100)
);
INSERT INTO #t1
(
[a],
[b],
[c]
)
VALUES
(5, 2, 'a*b');
DECLARE @cFormula AS NVARCHAR(20);
SELECT TOP 1
@cFormula = c
FROM #t1;
DECLARE @sql AS NVARCHAR(50) =
N'SELECT TOP 1 a, b, ' + @cFormula + ' AS cResult FROM #t1 AS t';
EXECUTE sp_executesql @sql;
DROP TABLE #t1;
产生:
a b cResult
5 2 10
这将适用于单行,因此您可以将此方法与一些循环机制结合使用,以迭代行,可能是游标。您没有提供任何额外的列来显示您是否有ID或可用于订购的内容,因此提供此答案时要记住这一点。这里的大多数人想要格式化的文本,而不是图像。您已经展示了一些示例公式,您只需要处理这些吗?还有,你有没有尝试过解决问题的方法,或者你只是在期待一个解决问题的答案?@Tanner,这是在期待一个关于如何推导的建议。公式将是dynamic@brahmareddy也许在文章中解释一下,并提供一些更复杂的例子,否则你会得到下面的答案。我想OP需要支持任意公式。@jarhl我想他需要not@RadimBa谢谢你的快速回复。但是我们需要它是动态的,我们不知道什么是公式,我们需要使用公式列static@brahmareddy很好,那么您应该更好地指定公式格式。仅仅是这四个操作是预期的吗?我会保留答案,这样人们就可以投票否决,而不是发布同样糟糕的解决方案,即使它返回预期的结果;感谢您提供的解决方案,有没有不使用循环的解决方案,因为我的表将至少有1个缺少的记录,列将更多
BEGIN TRAN
DECLARE @Strt INT ,@End INT
IF OBJECT_ID('TEMPDB..#t1') IS NOT NULL
DROP TABLE #t1
CREATE TABLE #t1
([a] int, [b] int, [c] varchar(100),[D] numeric(22,6))
;
INSERT INTO #t1
([a], [b], [c])
VALUES
(1, 2, 'a+b'),
(5, 6, 'a*b'),
(2, 1, 'a-b'),
(3, 8, 'b/a')
IF OBJECT_ID('TEMPDB..#TT') IS NOT NULL
DROP TABLE #TT
SELECT ROW_NUMBER()Over(Order by a)Rowno,* INTO #TT FROM #t1
SET @Strt =1
SELECT @End=MAX(Rowno)FROM #TT
WHILE @Strt <=@END BEGIN
DECLARE @Formula AS NVARCHAR(20),@sql NVARCHAR(MAX)
SELECT @Formula = c
FROM #TT WHERE Rowno = @Strt
SET @sql='
UPDATE #TT SET D ='+@Formula+'
WHERE Rowno ='''+Convert(Nvarchar,@Strt)+''''
PRINT @sql
EXECUTE(@sql)
SET @Strt= @Strt+1
END
SELECT * FROM #TT
ROLLBACK TRAN