Sql 根据帐号计算用户公式

Sql 根据帐号计算用户公式,sql,sql-server,Sql,Sql Server,我有两个表,第一个是dbo.formula Id | Poste | Calculation | Montant ---+--------+-------------+-------- 1 | Achats | 3801%+381% | ..... 2 | Tva | 446%-445% | .... 3 | Tiers | 411%+401% | .... 第二个表是dbo.value Compte | Solde --------+------- 380000

我有两个表,第一个是dbo.formula

Id | Poste  | Calculation | Montant
---+--------+-------------+--------
 1 | Achats | 3801%+381%  | .....
 2 | Tva    | 446%-445%   | ....
 3 | Tiers  | 411%+401%   | ....
第二个表是dbo.value

Compte  | Solde
--------+-------
 380000 | 400.00
 380100 | 500.00
 381100 | 200.00
 381200 | 100.00
4456600 | 100.00
4455400 | 150.00
我需要的结果在第一个表在外地蒙塔特喜欢

 1 | Achats | 3801%+381%   |..... = 500.00 + 200.00 + 100.00 = 800.00
 2 | Tva    | 446%-445%   |.... = 100.00 - 150.00 = -50.00
我尝试了一个请求,但它只适用于帐户的3个起始编号,并且只适用于+

select f.ID, f.Poste, sum(v.Solde) total
from formula f
inner join value v
    on charindex('+' + left(v.Compte, 3) + '%', '+' + f.Calculation) > 0
group by f.ID, f.Poste

我需要一个从数字account的1到8位数的请求,同时还需要使用+、-、*、/。

就我个人而言,我首先要创建一个新表,以更结构化的方式存储您的计算逻辑,而不是一个大的varchar:

create table calcs
(
    FormulaId int,
    operator varchar(1),
    pattern varchar(10)
)

insert into calcs
    select
        Id as FormulaId,
        case when left([value],1) like '[^0-9]' then left([value],1) else '+' end as operator,
        case when left([value],1) like '[^0-9]' then right([value],len([value])-1) else [value] end + '%' as pattern
    from formula
    cross apply string_split(Calculation, '%')
    where [value] <> ''

select * from calcs

Results:
/--------------------------------\
| FormulaId | operator | pattern |
|-----------|----------|---------|
|     1     |     +    | 3801%   |
|     1     |     +    | 381%    |
|     2     |     +    | 446%    |
|     2     |     -    | 445%    |
|     3     |     +    | 411%    |
|     3     |     +    | 401%    |
\--------------------------------/
如果您想整理第一个值为正数的前导
+
符号,可以将整个符号包装在另一个
选择中,或使用CTE:

with newFormula (Id, Poste, Calculation, Montant) as
(
    select
        f.Id,
        f.Poste,
        f.Calculation,
        (
            SELECT c.operator + convert(varchar(20),v.Solde)
            from calcs c
            join [value] v on v.Compte like c.pattern
            where c.FormulaId = f.Id
            for xml path('')
        )
        + ' = ' + convert(varchar(20),
                      sum(case when c2.operator = '+' then v2.Solde else 0 end) 
                    - sum(case when c2.operator = '-' then v2.Solde else 0 end)) as Montant
    from formula f
    left join calcs c2 on c2.FormulaId = f.Id
    left join [value] v2 on v2.Compte like c2.pattern
    group by f.Id, f.Poste, f.Calculation
)
select
    Id,
    Poste,
    Calculation,
    case when left(Montant,1) = '+'
        then right(Montant,len(Montant)-1)
        else Montant
    end as Montant
from newFormula

Results:
/------------------------------------------------------------\
| Id | Poste  | Calculation | Montant                        |
|----|--------|-------------|--------------------------------|
| 1  | Achats | 3801%+381%  | 500.00+200.00+100.00 = 800.00  |
| 2  | Tva    | 446%-445%   | -100.00-150.00 = -250.00       |
| 3  | Tiers  | 411%+401%   | NULL                           |
\------------------------------------------------------------/

为什么Tva的总数是-50而不是-250?
4456600
dbo.value.Compte
值是否有输入错误,且应以
446
开头?否则,在本例中,100和150都应该是负数,因此
Tva
的总数应该是-250?@Mohammed FETTAH。在试图解决这个问题之前,我想要更多的信息。解释这两个表是如何链接的。您希望结果是数字还是字符串?当它在金融公式中有意义时,为什么要这样使用
%
呢?我希望结果是一个数字我犯了一个错误,compte number是446600,dbo.value中为100.00,因为%是报表中类似的后面的所有数字选择445%,谢谢,它可以工作,但我只需要结果,而不是字段蒙塔特中的所有结果,例如,我只需要800.00有可能使用“*”或“/”?
with newFormula (Id, Poste, Calculation, Montant) as
(
    select
        f.Id,
        f.Poste,
        f.Calculation,
        (
            SELECT c.operator + convert(varchar(20),v.Solde)
            from calcs c
            join [value] v on v.Compte like c.pattern
            where c.FormulaId = f.Id
            for xml path('')
        )
        + ' = ' + convert(varchar(20),
                      sum(case when c2.operator = '+' then v2.Solde else 0 end) 
                    - sum(case when c2.operator = '-' then v2.Solde else 0 end)) as Montant
    from formula f
    left join calcs c2 on c2.FormulaId = f.Id
    left join [value] v2 on v2.Compte like c2.pattern
    group by f.Id, f.Poste, f.Calculation
)
select
    Id,
    Poste,
    Calculation,
    case when left(Montant,1) = '+'
        then right(Montant,len(Montant)-1)
        else Montant
    end as Montant
from newFormula

Results:
/------------------------------------------------------------\
| Id | Poste  | Calculation | Montant                        |
|----|--------|-------------|--------------------------------|
| 1  | Achats | 3801%+381%  | 500.00+200.00+100.00 = 800.00  |
| 2  | Tva    | 446%-445%   | -100.00-150.00 = -250.00       |
| 3  | Tiers  | 411%+401%   | NULL                           |
\------------------------------------------------------------/