[英]How to compare the first two rows in SQL Server
I am having the following tables for example purposes: 我有以下表格作为示例:
MTRL TABLE MTRL表
|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 |
I am currently using those two queries and then I am storing the output to a variable. 我当前正在使用这两个查询,然后将输出存储到变量中。 And I am doing the comparison with programming.
我正在与编程进行比较。 But instead of running two queries it would be better to run one and then take the output.
但是与其运行两个查询,不如运行一个查询然后获取输出,这会更好。
So I want to compare the last two prices. 所以我想比较最后两个价格。 If the last price has changed significantly or there is only one price like mtrl2 then output price1
如果最后一个价格已发生重大变化,或者只有一个价格(如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)
This is stored in variable price1
这存储在变量
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)
This is stored in variable price2
这存储在可变的
price2
I am doing programmaticaly something like (this one is vbscript): 我正在像编程一样做(这是vbscript):
If ABS(price1-price2)>0.02 Then
Result=Price1
Else
Result=0
End If
How could I achieve this with SQL only? 如何仅使用SQL来实现?
I might suggest: 我可能会建议:
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;
Note that your code does this one code at a time. 请注意,您的代码一次只能执行一个代码。 You can drop the
M.CODE = :kod_an
and run the code on more than one code. 您可以删除
M.CODE = :kod_an
并在多个代码上运行该代码。
Try something like this. 尝试这样的事情。 Didn't test it in absence of sample data, but the idea is to first get both rows (rn=1 and rn=2) in a CTE.
在没有样本数据的情况下没有对其进行测试,但是其想法是首先在CTE中获得两行(rn = 1和rn = 2)。 Then use
case
statements to find the abs
value and return 0
or PRICE
for rn=
. 然后,使用
case
语句查找abs
值,并为rn=
返回0
或PRICE
。
Also I am assuming that rest of your query is correct 我也假设您的其余查询是正确的
;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
;
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.