2017-06-02 61 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' –