问题
The Table data is as below, need to extract records that met the below conditions
Here Value = Value2-Value1
Value of two days back data should be > 2
Value of last day data is < 0
Value of next day data is < 4 and >0
Value of after next day data > 4
All the dates are weekdays,if any date falls on friday, need to compare with next day ie.. Monday. and comparision is with alternative days only
from below output have to be.
1 4-1-2018 15 18
2 3-1-2018 3 0
-----------------------------------
code Date Value1 Value2
---------------------------------------
1 1-1-2018 13 14
1 2-1-2018 14 18
1 3-1-2018 15 11
1 4-1-2018 15 18
1 5-1-2018 15 18
1 6-1-2018 11 18
1 7-1-2018 15 18
2 1-1-2019 1 3
2 2-1-2018 2 5
2 3-1-2018 3 0
2 4-1-2018 3 7
2 5-1-2018 3 4
2 6-1-2018 3 9
2 7-1-2018 3 7
I am pretty much confused at comparing multiple rows, any help is greatly appreciated.
回答1:
Starting with v2012 we have support for LAG() and LEAD(). Try this out:
SET DATEFORMAT dmy;
DECLARE @tbl TABLE(code INT,[Date] DATE,Value1 INT,Value2 INT);
INSERT INTO @tbl VALUES
(1,'1-1-2018',13,14)
,(1,'2-1-2018',14,18)
,(1,'3-1-2018',15,11)
,(1,'4-1-2018',15,18)
,(1,'5-1-2018',15,18)
,(1,'6-1-2018',11,18)
,(1,'7-1-2018',15,18)
,(2,'1-1-2019', 1, 3)
,(2,'2-1-2018', 2, 5)
,(2,'3-1-2018', 3, 0)
,(2,'4-1-2018', 3, 7)
,(2,'5-1-2018', 3, 4)
,(2,'6-1-2018', 3, 9)
,(2,'7-1-2018', 3, 7);
WITH cte AS
(
SELECT *
,LAG(Value2-Value1,2) OVER(PARTITION BY code ORDER BY [Date]) TwoDaysBack
,LAG(Value2-Value1,1) OVER(PARTITION BY code ORDER BY [Date]) Yesterday
,LEAD(Value2-Value1,1) OVER(PARTITION BY code ORDER BY [Date]) tomorrow
,LEAD(Value2-Value1,2) OVER(PARTITION BY code ORDER BY [Date]) TwoDaysAhead
FROM @tbl
)
SELECT *
FROM cte;
I do not really understand, how you want to use these values in a filter to get the expected output. If you need help with this, just come back...
The result
+------+------------+--------+--------+-------------+-----------+----------+--------------+
| code | Date | Value1 | Value2 | TwoDaysBack | Yesterday | tomorrow | TwoDaysAhead |
+------+------------+--------+--------+-------------+-----------+----------+--------------+
| 1 | 2018-01-01 | 13 | 14 | NULL | NULL | 4 | -4 |
+------+------------+--------+--------+-------------+-----------+----------+--------------+
| 1 | 2018-01-02 | 14 | 18 | NULL | 1 | -4 | 3 |
+------+------------+--------+--------+-------------+-----------+----------+--------------+
| 1 | 2018-01-03 | 15 | 11 | 1 | 4 | 3 | 3 |
+------+------------+--------+--------+-------------+-----------+----------+--------------+
| 1 | 2018-01-04 | 15 | 18 | 4 | -4 | 3 | 7 |
+------+------------+--------+--------+-------------+-----------+----------+--------------+
| 1 | 2018-01-05 | 15 | 18 | -4 | 3 | 7 | 3 |
+------+------------+--------+--------+-------------+-----------+----------+--------------+
| 1 | 2018-01-06 | 11 | 18 | 3 | 3 | 3 | NULL |
+------+------------+--------+--------+-------------+-----------+----------+--------------+
| 1 | 2018-01-07 | 15 | 18 | 3 | 7 | NULL | NULL |
+------+------------+--------+--------+-------------+-----------+----------+--------------+
| 2 | 2018-01-02 | 2 | 5 | NULL | NULL | -3 | 4 |
+------+------------+--------+--------+-------------+-----------+----------+--------------+
| 2 | 2018-01-03 | 3 | 0 | NULL | 3 | 4 | 1 |
+------+------------+--------+--------+-------------+-----------+----------+--------------+
| 2 | 2018-01-04 | 3 | 7 | 3 | -3 | 1 | 6 |
+------+------------+--------+--------+-------------+-----------+----------+--------------+
| 2 | 2018-01-05 | 3 | 4 | -3 | 4 | 6 | 4 |
+------+------------+--------+--------+-------------+-----------+----------+--------------+
| 2 | 2018-01-06 | 3 | 9 | 4 | 1 | 4 | 2 |
+------+------------+--------+--------+-------------+-----------+----------+--------------+
| 2 | 2018-01-07 | 3 | 7 | 1 | 6 | 2 | NULL |
+------+------------+--------+--------+-------------+-----------+----------+--------------+
| 2 | 2019-01-01 | 1 | 3 | 6 | 4 | NULL | NULL |
+------+------------+--------+--------+-------------+-----------+----------+--------------+
The idea in short:
Both, LAG() and LEAD() take an argument for the needed value, a second, how many rowswe want to skip, and as a third argument a default value you might specify to avoid NULLs in the result, when there is no row in scope.
The OVER() clause will tell any windowing function if we want to think of the set as divided in groups and the sort order (otherwise the system would not know what is leading or lagging.
回答2:
With lead and lag window functions:
with cte as (
select *,
lag(value2 - value1, 2) over (partition by code order by date) prev2,
lag(value2 - value1, 1) over (partition by code order by date) prev1,
lead(value2 - value1, 1) over (partition by code order by date) next1,
lead(value2 - value1, 2) over (partition by code order by date) next2
from tablename
)
select code, date, value1, value2
from cte
where prev2 > 2 and prev1 < 0 and next1 > 0 and next1 < 4 and next2 > 4
See the demo.
Results:
code | date | value1 | value2
---: | :------------------ | -----: | -----:
1 | 01/04/2018 00:00:00 | 15 | 18
2 | 01/04/2018 00:00:00 | 3 | 7
There is a difference between your expected results for code = 2
and my results, so check its validity.
来源:https://stackoverflow.com/questions/57823188/extract-data-by-comparing-4-different-rows