查找每组其他行的最大值

时间:2017-04-16 10:28:20

标签: oracle analytic-functions

我有一个包含值(ID)的简单表格(GRP_ID)。

create table tst as
select 1 grp_id, 1 id from dual union all
select 1 grp_id, 1 id from dual union all
select 1 grp_id, 2 id from dual union all
select 2 grp_id, 1 id from dual union all
select 2 grp_id, 2 id from dual union all
select 2 grp_id, 2 id from dual union all
select 3 grp_id, 3 id from dual; 

使用分析函数可以直接找到每组的最大值。

select grp_id, id,
max(id) over (partition by grp_id) max_grp
from tst
order by 1,2;

    GRP_ID         ID    MAX_GRP
---------- ---------- ----------
         1          1          2 
         1          1          2 
         1          2          2 
         2          1          2 
         2          2          2 
         2          2          2 
         3          3          3 

但目标是找到排除当前行值的最大值。

这是预期的结果(列MAX_OTHER_ID):

   GRP_ID         ID    MAX_GRP MAX_OTHER_ID
---------- ---------- ---------- ------------
         1          1          2            2 
         1          1          2            2 
         1          2          2            1 
         2          1          2            2 
         2          2          2            2  
         2          2          2            2 
         3          3          3              

请注意,在GRP_ID = 2中,MAX值存在一个平局,因此MAX_OTHER_ID保持不变。

我确实管理过这个两步解决方案,但我想知道是否有一个更简单明了的解决方案。

with max1 as (
select grp_id, id,
row_number() over (partition by grp_id order by id desc) rn
from tst
)
select GRP_ID, ID, 
case when rn = 1 /* MAX row per group */ then
  max(decode(rn,1,to_number(null),id)) over (partition by grp_id)
else
   max(id) over (partition by grp_id)
end as max_other_id   
from max1
order by 1,2

2 个答案:

答案 0 :(得分:4)

我希望窗口函数支持多种范围规范,例如:

max(id) over (
        partition by grp_id 
        order by id 
        range between unbounded preceding and 1 preceding
        or range between 1 following and unbounded following
        )

但不幸的是他们没有。

作为一种变通方法,您可以避免在不同范围内使用该函数两次的子查询和CTE,并在其上调用coalesce

select grp_id,
    id,
    coalesce(
            max(id) over (
                partition by grp_id
                order by id 
                range between 1 following and unbounded following
                )
            , max(id) over (
                partition by grp_id 
                order by id 
                range between unbounded preceding and 1 preceding
                )
            ) max_grp
from tst
order by 1,
    2
由于窗口函数调用的结果将是给定窗口中的最大值或空值,因此由于order子句,Coalesce开箱即用。

演示 - http://rextester.com/SDXVF13962

答案 1 :(得分:1)

public class MainActivity extends AppCompatActivity {
private ImageView imgOgImage;
private TextView text;
String URL = "https://www.youtube.com/watch?v=ufaK_Hd6BpI";
String UserAgent = "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/47.0.2526.106 Safari/537.36";

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    text = (TextView) findViewById(R.id.text);
    imgOgImage = (ImageView) findViewById(R.id.imgOgImage);
    new FetchMetadataFromURL().execute();

}

private class FetchMetadataFromURL extends AsyncTask<Void, Void, Void> {
    String websiteTitle, websiteDescription, imgurl;

    @Override
    protected void onPreExecute() {
        super.onPreExecute();

    }

    @Override
    protected Void doInBackground(Void... params) {
        try {
            // Connect to website
            Document document = Jsoup.connect(URL).get();
            // Get the html document title
            websiteTitle = document.title();




            //Here It's just print whole property of URL
            Elements metaElems = document.select("meta");
            for (Element metaElem : metaElems) {
                String property = metaElem.attr("property");
                Log.e("Property", "Property =" + property + " \n Value =" + metaElem.attr("content"));
            }


            // Locate the content attribute
            websiteDescription = metaElems.attr("content");
            String ogImage = null;
            Elements metaOgImage = document.select("meta[property=og:image]");
            if (metaOgImage != null) {
                imgurl = metaOgImage.first().attr("content");
                System.out.println("src :<<<------>>> " + ogImage);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

    @Override
    protected void onPostExecute(Void result) {
        text.setText("Title : " + websiteTitle + "\n\nImage Url :: " + imgurl);

        //t2.setText(websiteDescription);
        Picasso.with(getApplicationContext()).load(imgurl).into(imgOgImage);

    }

}

使用Co-Related Query获得预期结果!希望这会有所帮助。