根据另一个表

时间:2017-03-01 12:44:15

标签: text expression

我有两张桌子:

TBL1:

MetricID    Date    Value   
SC-1a    2/27/2017  883     
SC-1b    2/27/2017  1025    
SC-2a    2/27/2017  734     
SC-2b    2/27/2017  291     
SC-2c    2/27/2017  0   
SC-2d    2/27/2017  19  
SC-2e    2/27/2017  0   
SC-2f    2/27/2017  58  
SC-2g    2/27/2017  1   
SC-2h    2/27/2017  0   
SC-2i    2/27/2017  0

TBL2:

MetricID    MetricCalc
SC-1        SC-1a / SC-1b
SC-2       ((SC-2a + SC-2b + SC-2c) - (SC-2d + SC-2e + SC-2f + SC-2g + SC-2h + SC-2i)) / (SC-2a + SC-2b + SC-2c)

是否有可能在Tbl2中使用Tbl1中的相应值来评估特定日期的表达式?

例如:2017年2月27日 SC-1a / SC-1b将评估为883/1025 = 0.8614和 ((SC-2a + SC-2b + SC-2c) - (SC-2d + SC-2e + SC-2f + SC-2g + SC-2h + SC-2i))/(SC-2a + SC-2b) + SC-2c)将评估为((734 + 291 + 0) - (19 + 0 + 58 + 1 + 0 + 0))/(734 + 291 + 0)= 0.9239

搜索Google提供的链接,用于评估其中包含直接数字的数学表达式。在这种情况下,表达式中的文本需要替换为相应的数字,然后进行评估。我对SQL很新,任何帮助都会受到赞赏。谢谢你的帮助。

问题也发布在https://www.sqlservercentral.com/Forums/1861974/Evaluating-a-Text-Expression-based-on-Values-from-another-table

1 个答案:

答案 0 :(得分:0)

我在SSC上做出的答案,但由于OP没有回应耗材DDL和样品数据请求而在此发布。:

CREATE TABLE #Metrics (MetricID VARCHAR(5),
                       MetricDate DATE,
                       MetricValue INT);

CREATE TABLE #Calculations (CalculationID VARCHAR(4), --These shouldn't have the same name in both tables as they are not the same thing
                            Calculation VARCHAR(500));
GO
INSERT INTO #Metrics
VALUES
('SC-1a','20170227',883),     
('SC-1b','20170227',1025),
('SC-2a','20170227',734),    
('SC-2b','20170227',291),   
('SC-2c','20170227',0),
('SC-2d','20170227',19),  
('SC-2e','20170227',0),   
('SC-2f','20170227',58),  
('SC-2g','20170227',1),   
('SC-2h','20170227',0),   
('SC-2i','20170227',0);

INSERT INTO #Calculations
VALUES
('SC-1','SC-1a / SC-1b'),
('SC-2', '((SC-2a + SC-2b + SC-2c) - (SC-2d + SC-2e + SC-2f + SC-2g + SC-2h + SC-2i)) / (SC-2a + SC-2b + SC-2c)');
GO

SELECT CalculationID, Calculation, 1 AS RN
FROM #Calculations C
     LEFT JOIN #Metrics M ON PATINDEX('%' + M.MetricID + '%', C.Calculation) > 0
WHERE C.CalculationID = 'SC-1'

GO
DECLARE @DATE DATE = '27-Feb-2017';

WITH Replacements AS (
    SELECT CalculationID, Calculation, Calculation As CastCalculation, 1 AS RN
    FROM #Calculations C
    --WHERE C.CalculationID = 'SC-1'

    UNION ALL

    SELECT R.CalculationID,
           CAST(REPLACE(R.Calculation, M.MetricID, CAST(M.MetricValue AS varchar(100))) AS varchar(500)),
           CAST(REPLACE(R.Calculation, M.MetricID, 'CAST(' + CAST(M.MetricValue AS varchar(100)) + ' AS decimal(12,4))') AS varchar(500)),
           RN + 1
    FROM Replacements R
         JOIN #Metrics M ON PATINDEX('%' + M.MetricID + '%', R.Calculation) > 0
                        AND M.MetricDate = @Date
                        AND CHAR(RN + 96) = RIGHT(M.MetricID,1)
                        )
SELECT *
INTO #DSQL
FROM Replacements R
WHERE RN = (SELECT MAX(sq.RN) FROM Replacements sq WHERE sq.CalculationID = R.CalculationID);

DECLARE @SQL VARCHAR(MAX);

SELECT @SQL = STUFF((SELECT 'UNION ALL' + CHAR(10) + 'SELECT ''' + CalculationID + ''' AS CalculationID, ''' + Calculation + ''' AS Calculation, ' + CastCalculation + ' AS CalculatedMetricValue' + CHAR(10)
                     FROM #DSQL
                     FOR XML PATH('')),1,10,'')

SELECT @SQL;

EXEC (@SQL);

DROP TABLE #DSQL;

GO
--Clean up
DROP TABLE #Metrics;
DROP TABLE #Calculations;

P.S。是的,我知道我不需要临时表#DSQL,我可以把CTE替换的结果。主要原因是我在那时将其分开,以便我可以将思维过程分开,然后我就不再费心将两者合并在一起了。