如何比较SQL Server

时间:2017-06-02 09:58:52

标签: sql sql-server sql-server-2008

我出于示例目的使用以下表格:

MTRL TABLE

|MTRL|  CODE  |
---------------
| 1  | 080109 |
| 2  | 085145 |
| 3  | 084141 |

MTRLINES TABLE

|MTRL|  PRICE  | FINDOC |
-------------------------
| 1  |  4.95   | 12345  |
| 1  |  4.50   | 23421  |
| 1  |  3.90   | 23499  |


|MTRL|  PRICE  | FINDOC |
-------------------------
| 2  |  2.95   | 45345  |

我目前正在使用这两个查询,然后我将输出存储到变量中。我正在与编程进行比较。 但不是运行两个查询,而是运行一个然后获取输出更好。

所以我想比较最后两个价格。如果最后一个价格发生了显着变化,或者只有一个价格如mtrl2那么输出price1

SELECT 
      , SUB.PRICE
FROM (
        SELECT 
              , ML.PRICE
              , rn = row_number() over (PARTITION BY M.CODE ORDER BY FINDOC DESC)
        FROM  MTRLINES ML
              INNER JOIN MTRL M
                    ON M.MTRL = ML.MTRL  AND FINDOC IN (SELECT FINDOC FROM FINDOC WHERE SOSOURCE=1251 AND FPRMS IN (1,2)) 
              WHERE  M.SODTYPE=51 AND M.COMPANY=1 AND M.CODE=:kod_an
      ) sub
WHERE rn IN (1)

这存储在变量price1

SELECT 
      , SUB.PRICE
FROM (
        SELECT 
              , ML.PRICE
              , rn = row_number() over (PARTITION BY M.CODE ORDER BY FINDOC DESC)
        FROM  MTRLINES ML
              INNER JOIN MTRL M
                    ON M.MTRL = ML.MTRL  AND FINDOC IN (SELECT FINDOC FROM FINDOC WHERE SOSOURCE=1251 AND FPRMS IN (1,2)) 
              WHERE  M.SODTYPE=51 AND M.COMPANY=1 AND M.CODE=:kod_an
      ) sub
WHERE rn IN (2)

这存储在变量price2

我正在做程序化的事情(这个是vbscript):

If ABS(price1-price2)>0.02 Then
    Result=Price1
Else
    Result=0
End If

我怎样才能用SQL实现这个目标?

2 个答案:

答案 0 :(得分:2)

我可能会建议:

with prices as (
      select code,
             max(case when seqnum = 1 then price end) as price_last,  
             max(case when seqnum = 2 then price end) as price_second,
             count(*) as num_prices 
      from (select ml.price, m.code,
                   row_number() over (partition by M.CODE order by FINDOC desc) as seqnum
            from MTRLINES ML inner join
                 MTRL M
                 ON M.MTRL = ML.MTRL and
                    FINDOC in (select FINDOC from FINDOC where SOSOURCE = 1251 and FPRMS in (1, 2)
                              ) 
            where M.SODTYPE = 51 and M.COMPANY = 1 and
                  M.CODE = :kod_an
           ) m
      where seqnum in (1, 2)
      group by code
     )
select (case when num_prices = 1 then price_last
             when abs(price_last - price_second) > 0.02 then price_last
             else 0
        end)
from prices;

请注意,您的代码一次执行此代码。您可以删除M.CODE = :kod_an并在多个代码上运行代码。

答案 1 :(得分:0)

尝试这样的事情。在没有样本数据的情况下没有测试它,但想法是首先在CTE中获得两行(rn = 1和rn = 2)。然后使用case语句查找abs值,并为0返回PRICErn=

此外,我假设您的其他查询是正确的

;with t as (
SELECT 
      SUB.PRICE
FROM (
        SELECT 
               ML.PRICE
              , rn = row_number() over (PARTITION BY M.CODE ORDER BY FINDOC DESC)
        FROM  MTRLINES ML
              INNER JOIN MTRL M
                    ON M.MTRL = ML.MTRL  AND FINDOC IN (SELECT FINDOC FROM FINDOC WHERE SOSOURCE=1251 AND FPRMS IN (1,2)) 
              WHERE  M.SODTYPE=51 AND M.COMPANY=1 AND M.CODE=:kod_an
      ) sub
WHERE rn IN (1,2)
)
select case 
            when abs(sum(case when rn=1 
                            then price 
                            else (price * -1 ) 
                        end)
                    )
                    > 0.02  
        then (select price1 from t where rn=1) 
        else 0 end
         as result
from t
;