2017-06-02 31 views
0

我有例如目的,下面的表格比较:如何在SQL Server中的前两行

MTRL表

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

MTRLINES表

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


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

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

所以我想比较最后两个价格。如果最后价格显著改变,或者只存在一个价格像mtrl2然后输出价格1

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

我做一些像programmaticaly(这是vbscript):

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

我怎么才能用SQL实现这一点?

回答

1

我可能会建议:

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并在多个代码上运行代码。

+0

这很好!只需用'-'修正'>'谢谢! –

+0

当mtrlines表有一行时,例如一个价格返回0.它应该返回Price1。请看看它。它有两行或更多行时有效... –

+0

@ F.Mysir。 。 。一种方法是对价格进行计数,并在逻辑中明确包含这些价格 –

0

尝试类似这样的东西。在没有样本数据的情况下没有对其进行测试,但是想法是首先在CTE中获得两行(rn = 1和rn = 2)。然后使用case语句查找abs值并返回0PRICE代替rn=

我也是假设您的查询的是剩下的就是正确的

;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 
; 
+0

嗨,它说无效列名'rn' –