简体   繁体   English

SQL根据另一行中的值排除行

[英]SQL exclude rows based on value in another row

I am trying to exclude rows where a value exists in another row. 我正在尝试排除另一行中存在值的行。

select * from TABLE1

ROW SEQ VALUE
1   1   HIGH
1   2   HIGH
1   3   LOW
1   4   HIGH
2   1   MED
2   2   HIGH
2   3   HIGH
2   4   LOW
2   5   HIGH
2   6   HIGH

All the data is coming from the same table what I am trying to do is exclude the rows where VALUE = 'LOW' and all previous rows where SEQ <= the row with the value = 'LOW'. 我试图做的所有数据都来自同一张表,是排除VALUE ='LOW'的行以及SEQ <=值='LOW'的行。 This is my desired result: 这是我想要的结果:

 ROW SEQ VALUE
1   4   HIGH
2   5   HIGH
2   6   HIGH

Here's work in progress but it's only excluding the one row 这是正在进行的工作,但仅排除了一行

select * from TABLE1
where not exists(select VALUE from TABLE1 
where ROW = ROW and VALUE = 'LOW' and SEQ <= SEQ)

I need to write it into the where cause as the select is hard coded. 由于选择是硬编码的,因此我需要将其写入where原因。 I am lost any help would be greatly appreciated. 我失去了任何帮助,将不胜感激。 Thanks in advance! 提前致谢!

select *
from table1
left outer join (
    select row, max(seq) as seq
    from table1
    where value = 'low'
    group by row
) lows on lows.row = table1.row
where lows.row is null
   or table1.seq > lows.seq

You should be aliasing the tables. 您应该为表加上别名。 I'm surprised you are getting any results from this query as you don't have aliases at all. 我很惊讶您从此查询中获得任何结果,因为您根本没有别名。

select * 
from TABLE1 As t0
where not exists(
    select VALUE 
    from TABLE1 As t1
    where t0.ROW = t1.ROW 
    and t1.VALUE = 'LOW' 
    and t0.SEQ <= t1.SEQ
)

For the results you mention, you seem to want the rows after the last "low". 对于您提到的结果,您似乎想要最后一个“低”之后的行。 One method is: 一种方法是:

select t1.*
from table1 t1
where t1.seq > (select max(t2.seq) from table1 tt1 where tt1.row = t1.row and tt1.value = 'LOW');

(Note: This requires a "low" row. If there could be no "low" rows and you want all rows returned, that is easily added to the query.) (注意:这需要一个“低”行。如果可能没有“低”行,并且您希望返回所有行,则可以轻松地将其添加到查询中。)

Or, similarly, using not exists : 或者,类似地,使用not exists

select t1.*
from table1 t1
where not exists (select 1
                  from table1 tt1 
                  where tt1.row = t1.row and
                        tt1.seq > t.seq and
                        tt1.value = 'LOW'
                 );

This might be the most direct translation of your question. 这可能是您问题的最直接翻译。

However, I would more likely use window functions: 但是,我更可能使用窗口函数:

select t1.*
from (select t1.*,
             max(case when t1.value = 'low' then seqnum end) over (partition by row) as max_low_seqnum
      from table1 t1
     ) t1
where seqnum > max_low_seqnum;

You might want to add or max_low_seqnum is null to return all rows if there are no "low" rows. 如果没有“低”行,则可能要添加or max_low_seqnum is null以返回所有行。

You can use a window function with a cumulative approach : 您可以将窗口函数与累积方法一起使用:

select t.*
from (select t.*, sum(case when value = 'LOW' then 1 else 0 end) over (partition by row order by seq) as cnt
      from table t
     ) t
where cnt = 1 and value <> 'LOW';

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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