简体   繁体   中英

Selecting rows based on condition for value pairs in group

I've been trying to solve an issue for the past couple of days, which I can explain well enough with a simplifying example:

I have a table such as the following:

> Row number   ID      Value1   Value2   
       1       1        4       10   ---
       2       1        2        9   ---
       3       1        3        8
       4       1        2        7    
       5       1        2        6
       6       1        1        5   ---
       7       1        1        4
       8       1        1        3
       9       2        8        21        
            .
            .
            .

Each ID having a non-relevant amount of rows for value1 (v1) and value2 (v2).

What I need is to select the rows for which there is no other row that satisfies the condition of value1.other_row <= value1.selected_row and value2.other_row > value2.selected_row. This must be verified by group of similar ID's.

For example, row number 5 shouldn't be accepted, because looking at row 4 (r4), although v1(r4) = v1(r5) , it is verified that v2(r4) > v2(r5).

On the other hand, row 6 should be accepted, seen that no other row in group ID=1 has v1 less or equal than its own, while having a larger v2!

Following this logic, only the rows that have --- in front of them should be accepted.

I have tried self JOIN, together with defining the condition using the ON clause, but couldn't understand how to test every row in a group for every other row .

Can anyone help me with this objective? Thank you very much.

A NOT EXISTS clause would seem to work well here:

SELECT t1.*
FROM yourTable t1
WHERE NOT EXISTS (SELECT 1 FROM yourTable t2
                  WHERE t1.value1 >= t2.value1 AND t1.value2 < t2.value2);

在此处输入图片说明

Demo

Here is an alternative solution with self-join:

CREATE TABLE #temp (RN INT, ID INT, Value1 INT, Value2 INT)
INSERT INTO #temp 
SELECT 1, 1 , 4, 10 UNION ALL -- match
    SELECT 2, 1, 2, 9 UNION ALL -- match
    SELECT 3, 1, 3, 8 UNION ALL
    SELECT 4, 1, 2, 7 UNION ALL
    SELECT 5, 1, 2, 6 UNION ALL
    SELECT 6, 1, 1, 5 UNION ALL -- match
    SELECT 7, 1, 1, 4 UNION ALL
    SELECT 8, 1, 1, 3 UNION ALL
    SELECT 9, 2, 8, 21


SELECT * FROM #temp WHERE RN NOT IN (
   SELECT t1.RN
   FROM #temp t1
   INNER JOIN #temp t2 on t1.ID=t2.ID and t1.value1 >= t2.value1 AND t1.value2 < t2.value2
)

Output:

在此处输入图片说明

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM