sql - T-SQL 将算术公式转换为其组件
问题描述
问题陈述:我有一个公式列,其中包含算术运算。我想从公式中提取变量名称,并用逗号分隔变量并创建一个新列“公式组件”
The variable names follow the particular pattern - '%[^A-Za-z,_0-9 ]%'
但是,如果“方括号”要出现在公式中,我也想保留它们。
为了显示,
输入数据:
ID | Formula
------|-------------------------------------------
1 | ([x1] + [x2]) / 100
2 | ([y1] - [x2]) * 100
3 | z1 - z3
4 | [z4] % z3
5 | ((x1 * 2) + ((y1 + 2)/[x1])*[z3])/100
期望的输出
ID | Formula | FormulaComponents
------|------------------------------------------ |-----------------
1 | ([x1] + [x2]) / 100 | [x1],[x2]
2 | ([y1] - [x2]) * 100 | [y1],[x2]
3 | z1 - z3 | [z1],[z3]
4 | [z4] % z3 | [z4],[z3]
5 | ((x1 * 2) + ((y1 + 2)/[x1])*[z3])/100 | [x1],[y1],[z3]
正如你在上面看到的,
- 第 1 行。公式列由两个变量组成,因此公式分量为 [x1],[x2]
- 第 5 行。注意 x1 在公式中出现了两次;一次为 x1,一次为 [x1]。在这种情况下,我只想保留 [x1] 一次。[x1] 可以在公式列中出现 N 次,但在 FormulaComponents 列中应该只出现一次
PS:“FormulaComponents”列中出现的变量顺序无关紧要。例如,在第 5 行,顺序可以是 [y1]、[z3]、[x1] OR [z3]、[x1]、[y1] 等等
总结一下:我想在 T-SQL 中编写一个 SELECT 语句来创建这个新列。
解决方案
您可以使用拆分字符串string_split()
,然后仔细重新聚合结果:
select *
from t cross apply
(select string_agg('[' + value + ']', ',') as components
from (select distinct replace(replace(value, '[', ''), ']', '') as value
from string_split(replace(replace(replace(replace(t.formula, '(', ' '), ')', ' '), '*', ' '), '/', ' '), ' ') s
where value like '[[a-z]%'
) s
) s;
这是一个 db<>fiddle。
这比必要的更难,因为您的公式没有规范格式。如果所有变量都用方括号括起来会更简单。或者,如果所有运算符都被空格包围。
编辑:
SQL Server 2016 有string_split()
但没有string_agg()
. 该风扇将替换为 XML“东西”:
您可以使用拆分字符串string_split()
,然后仔细重新聚合结果:
select *
from t cross apply
(select stuff( (select distinct ',[' + value + ']'
from (select distinct replace(replace(value, '[', ''), ']', '') as value
from string_split(replace(replace(replace(replace(t.formula, '(', ' '), ')', ' '), '*', ' '), '/', ' '), ' ') s
where value like '[[a-z]%'
) t
order by 1
for xml path ('')
), 1, 1, '') as components
) s;
推荐阅读
- python - Django 休息框架 | Knox 身份验证密码未在数据库中散列
- spring-data - 在简单的应用程序中使用 Spring Data 获取 Arango 存储库的不满意依赖项
- java - 如何强制子 spring boot jar 从父 spring boot 读取属性
- mysql - 如何在 ORM Symfony 4 中将列的数据类型从 STRING 更改为 TEXT?
- php - PHP:在不区分大小写的情况下获取文件
- javascript - 如何在 xamarin 的 webview 应用程序中从 js 运行 ac# 方法
- odoo-12 - 更改因为删除而出现的错误消息
- swift - Metal:为 MSL cikernel 设置编译器和链接器选项后,.metal 文件中定义的 vertexFunction 变为 nil
- oracle - 即使在授予豁免政策之后,Exchange 子分区也因 VPD 而失败
- javascript - 如果有一些验证,Ctrl+A 在输入框上的 Firefox 中不起作用