在SQL中处理SI前缀

时间:2017-10-08 23:38:08

标签: sql sql-server

我在SQL Server数据库中有许多跟踪电子组件的表。

因此,我有一个具有“'值”的电阻器。在0到10M之间,以及具有“'值”的电容器。在1p和1u之间。

我想对这些值执行简单的数学运算,但必须首先考虑SI前缀。

有关如何在SQL中完成此操作的任何建议吗?大多数相关问题似乎都使用python等来完成数据库外部的工作。在我的情况下,这不是一个选项。

编辑:要求提供进一步的信息

我有'价值'由工程师填充的字段,因此它们以3n3,2.2k,1M等格式存储为varchar。可能有小数点,或SI前缀充当小数点。 这些数据的主要目的是显示原理图,因此是丑陋的人类可读格式。 我的问题具体是关于如何将人类可读的值解释为科学记数法(或统一量表),以便它们的数值解释可用于SQL服务器内的计算。

2 个答案:

答案 0 :(得分:2)

您的案例确实需要更好的描述。

但从基础开始,您需要选择1个单位作为数据库的基本单位。 (好的,所以1个电阻器单元,1个电容器单元) 将所有值存储在该基本单元中。 存储“外部世界”单元是一个单独的列。

现在您的所有值都在同一个单元中,您可以对它们执行计算。 当需要输出到外部世界时,使用查找表转换为所需的任何单位。

因此:

    create table test.resistors(
    name nvarchar(1000)
    ,value int
    ,unit smallint
)
insert into test.resistors([name],[value],[unit])
values('2 milliOhms resistor',2,1)
insert into test.resistors([name],[value],[unit])
values('2000 Ohm resistor',2,3)
insert into test.resistors([Name],[value],[unit])
values('10 Meg resistor',10,4)


create table test.resistorUnits(
    code smallint identity(1,1)
    ,name nvarchar(60)
    ,Ohms float
)
insert into test.resistorUnits([name],[Ohms])
values('m',.0001)
insert into test.resistorUnits([name],[Ohms])
values('Ohms',1)
insert into test.resistorUnits([name],[Ohms])
values('k',1000)
insert into test.resistorUnits([name],[Ohms])
values('M',1000000)

select 
    R.name,  R.value * U.Ohms as [Value in Ohms], cast(R.value as nvarchar) + ' ' + U.name as [Original Value]
from test.resistors R inner join test.resistorUnits U
        on R.unit = U.code

enter image description here

答案 1 :(得分:2)

无论如何,这会取消前缀;您可能希望将这些相互相乘,在这种情况下,您将需要由数字乘以前缀所代表的数字所代表的“大数字”。如果是这样,请告诉我,因为这是可行的。如果你打算单独对每个数字进行数学运算,我认为这将是令人满意的。

CREATE TABLE Component_Values
(
ID INT IDENTITY(11,1),
[value] nvarchar(11)
)
INSERT INTO Component_Values VALUES ('815.048u')
INSERT INTO Component_Values VALUES ('90.3m')
INSERT INTO Component_Values VALUES ('3659.88105d')
INSERT INTO Component_Values VALUES ('260.976da')
INSERT INTO Component_Values VALUES (651.8098)
INSERT INTO Component_Values VALUES ('88.917Y')
INSERT INTO Component_Values VALUES ('54.8673p')
INSERT INTO Component_Values VALUES ('75.256G')
INSERT INTO Component_Values VALUES ('121.9183T')
INSERT INTO Component_Values VALUES ('88.657y')
INSERT INTO Component_Values VALUES ('0.001Z')
INSERT INTO Component_Values VALUES ('86E')
INSERT INTO Component_Values VALUES ('8878.99P')
INSERT INTO Component_Values VALUES ('2.3758z')
INSERT INTO Component_Values VALUES ('9899.22a')
INSERT INTO Component_Values VALUES ('4578.999f')
INSERT INTO Component_Values VALUES ('766n')
INSERT INTO Component_Values VALUES ('8.021c')
INSERT INTO Component_Values VALUES ('7644.0984h')
INSERT INTO Component_Values VALUES ('8787.223k')
INSERT INTO Component_Values VALUES ('7M')

CREATE TABLE #Number
(
ID INT,
[Number] Float
)
INSERT INTO #Number
SELECT
ID, 
CASE WHEN RIGHT([value],2) NOT LIKE '[a-z][a-z]' AND RIGHT([value],1)
                           NOT LIKE '[0-9]' 
                           THEN (left([value],len([value])-1))
     WHEN RIGHT([value],2) LIKE '[a-z][a-z]' 
                           THEN (left([value],len([value])-2))
     ELSE [VALUE]
 END
 FROM Component_Values

 SELECT * FROM #Number