查看: 583|回复: 5

求一个query

[复制链接]
论坛徽章:
13
2010新春纪念徽章
日期:2010-03-01 11:04:59技术图书徽章
日期:2018-03-01 10:21:49秀才
日期:2018-03-01 10:21:252015年新春福章
日期:2015-03-06 11:58:18喜羊羊
日期:2015-03-04 14:52:46优秀写手
日期:2014-04-22 06:00:18马上有对象
日期:2014-02-18 16:44:082014年新春福章
日期:2014-02-18 16:44:082013年新春福章
日期:2013-02-25 14:51:242012新春纪念徽章
日期:2012-01-04 11:56:01
发表于 2019-8-9 12:17 | 显示全部楼层 |阅读模式
要找出ID对应的最大的DT, 规则是:如果所有的IND 都是S, 就找出每个ID中最大的DT, 如果任意一个ID 有IND 是 N, 那么, 所有ID 都取 ID 有IND 是 N当中 IND = S 的最大的DT。
每次只可能一个ID 有IND =N。而且, N 一定出现在最大的DT 中。
下面的例子中, 因为ID = 1的数据中有IND = N, 而这个ID 中IND=S 最大的DT 是20, 所以所有的DT 都是20
WITH t
     AS (SELECT 1 ID, 10 DT, 'S' IND FROM DUAL
         UNION ALL
         SELECT 1 ID, 20 DT, 'S' IND FROM DUAL
         UNION ALL
         SELECT 1 ID, 30 DT, 'N' IND FROM DUAL
         UNION ALL
         SELECT 2 ID, 10 DT, 'S' IND FROM DUAL
         UNION ALL
         SELECT 2 ID, 20 DT, 'S' IND FROM DUAL
         UNION ALL
         SELECT 2 ID, 30 DT, 'S' IND FROM DUAL
         UNION ALL
         SELECT 3 ID, 30 DT, 'S' IND FROM DUAL
         UNION ALL
         SELECT 3 ID, 40 DT, 'S' IND FROM DUAL
         UNION ALL
         SELECT 3 ID, 50 DT, 'S' IND FROM DUAL)
SELECT ID, DT, IND
  FROM T;

ID        DT        IND
1        10        S
1        20        S
1        30        N
2        10        S
2        20        S
2        30        S
3        30        S
3        40        S
3        50        S
上面的数据因为有那条 IND=N 的记录, 所以所有的DT都是20
1
20
2
20
3
20
如果没有IND=N 的记录,结果是下面的
1
30
2
30
3
50








论坛徽章:
466
生肖徽章2007版:猴
日期:2008-05-16 11:28:59生肖徽章2007版:马
日期:2008-10-08 17:01:01SQL大赛参与纪念
日期:2011-04-13 12:08:17授权会员
日期:2011-06-17 16:14:53ITPUB元老
日期:2011-06-21 11:47:01ITPUB官方微博粉丝徽章
日期:2011-07-01 09:45:27ITPUB十周年纪念徽章
日期:2011-09-27 16:30:472012新春纪念徽章
日期:2012-01-04 11:51:22海蓝宝石
日期:2012-02-20 19:24:27铁扇公主
日期:2012-02-21 15:03:13
发表于 2019-8-9 13:07 | 显示全部楼层
没N,有一个N,有多个N , 3个例子:

SQL> with t
  2       as (select 1 id, 10 dt, 'S' ind from dual
  3           union all
  4           select 1 id, 20 dt, 'S' ind from dual
  5           union all
  6           select 1 id, 30 dt, 'S' ind from dual
  7           union all
  8           select 2 id, 10 dt, 'S' ind from dual
  9           union all
10           select 2 id, 20 dt, 'S' ind from dual
11           union all
12           select 2 id, 30 dt, 'S' ind from dual
13           union all
14           select 3 id, 30 dt, 'S' ind from dual
15           union all
16           select 3 id, 40 dt, 'S' ind from dual
17           union all
18           select 3 id, 50 dt, 'S' ind from dual)
19  select a.id,b.max_dt max_dt
20    from (
21  select id
22    from t
23     where exists (select 'x'
24                     from t
25                     where ind = 'N')
26     group by t.id) a,
27  (select max(lag_dt) max_dt
28              from (
29            select id, dt, ind,lag(dt) over(partition by id order by dt) lag_dt
30              from t
31             where id in (select id
32                            from t
33                           where ind = 'N')
34                          )
35           ) b
36  union all
37  select id, max(dt) max_dt
38    from t
39   where not exists (select 'x'
40                       from t
41                      where ind = 'N')
42    group by id
43    order by id
44  /

        ID     MAX_DT
---------- ----------
         1         30
         2         30
         3         50

SQL>
SQL>
SQL>
SQL>
SQL> with t
  2       as (select 1 id, 10 dt, 'S' ind from dual
  3           union all
  4           select 1 id, 20 dt, 'S' ind from dual
  5           union all
  6           select 1 id, 30 dt, 'N' ind from dual
  7           union all
  8           select 2 id, 10 dt, 'S' ind from dual
  9           union all
10           select 2 id, 20 dt, 'S' ind from dual
11           union all
12           select 2 id, 30 dt, 'S' ind from dual
13           union all
14           select 3 id, 30 dt, 'S' ind from dual
15           union all
16           select 3 id, 40 dt, 'S' ind from dual
17           union all
18           select 3 id, 50 dt, 'S' ind from dual)
19  select a.id,b.max_dt max_dt
20    from (
21  select id
22    from t
23     where exists (select 'x'
24                     from t
25                     where ind = 'N')
26     group by t.id) a,
27  (select max(lag_dt) max_dt
28              from (
29            select id, dt, ind,lag(dt) over(partition by id order by dt) lag_dt
30              from t
31             where id in (select id
32                            from t
33                           where ind = 'N')
34                          )
35           ) b
36  union all
37  select id, max(dt) max_dt
38    from t
39   where not exists (select 'x'
40                       from t
41                      where ind = 'N')
42    group by id
43    order by id
44  /

        ID     MAX_DT
---------- ----------
         1         20
         2         20
         3         20

SQL>     
SQL>
SQL>
SQL>
SQL>
SQL> with t
  2       as (select 1 id, 10 dt, 'S' ind from dual
  3           union all
  4           select 1 id, 20 dt, 'S' ind from dual
  5           union all
  6           select 1 id, 30 dt, 'N' ind from dual
  7           union all
  8           select 2 id, 10 dt, 'S' ind from dual
  9           union all
10           select 2 id, 20 dt, 'S' ind from dual
11           union all
12           select 2 id, 30 dt, 'S' ind from dual
13           union all
14           select 3 id, 30 dt, 'S' ind from dual
15           union all
16           select 3 id, 40 dt, 'S' ind from dual
17           union all
18           select 3 id, 50 dt, 'N' ind from dual)
19  select a.id,b.max_dt max_dt
20    from (
21  select id
22    from t
23     where exists (select 'x'
24                     from t
25                     where ind = 'N')
26     group by t.id) a,
27  (select max(lag_dt) max_dt
28              from (
29            select id, dt, ind,lag(dt) over(partition by id order by dt) lag_dt
30              from t
31             where id in (select id
32                            from t
33                           where ind = 'N')
34                          )
35           ) b
36  union all
37  select id, max(dt) max_dt
38    from t
39   where not exists (select 'x'
40                       from t
41                      where ind = 'N')
42    group by id
43    order by id
44  /

        ID     MAX_DT
---------- ----------
         1         40
         2         40
         3         40

SQL>

使用道具 举报

回复
论坛徽章:
535
奥运会纪念徽章:垒球
日期:2008-09-15 01:28:12生肖徽章2007版:鸡
日期:2008-11-17 23:40:58生肖徽章2007版:马
日期:2008-11-18 05:09:48数据库板块每日发贴之星
日期:2008-11-29 01:01:02数据库板块每日发贴之星
日期:2008-12-05 01:01:03生肖徽章2007版:虎
日期:2008-12-10 07:47:462009新春纪念徽章
日期:2009-01-04 14:52:28数据库板块每日发贴之星
日期:2009-02-08 01:01:03生肖徽章2007版:蛇
日期:2009-03-09 22:18:532009日食纪念
日期:2009-07-22 09:30:00
发表于 2019-8-9 23:52 | 显示全部楼层
WITH t
     AS (SELECT 1 ID, 10 DT, 'S' IND FROM DUAL
         UNION ALL
         SELECT 1 ID, 20 DT, 'S' IND FROM DUAL
         UNION ALL
         SELECT 1 ID, 30 DT, 'N' IND FROM DUAL
         UNION ALL
         SELECT 2 ID, 10 DT, 'S' IND FROM DUAL
         UNION ALL
         SELECT 2 ID, 20 DT, 'S' IND FROM DUAL
         UNION ALL
         SELECT 2 ID, 30 DT, 'S' IND FROM DUAL
         UNION ALL
         SELECT 3 ID, 30 DT, 'S' IND FROM DUAL
         UNION ALL
         SELECT 3 ID, 40 DT, 'S' IND FROM DUAL
         UNION ALL
         SELECT 3 ID, 50 DT, 'S' IND FROM DUAL)
SELECT ID
      ,NVL(MAX(CASE WHEN MAX(CASE WHEN IND='N' THEN IND END)='N' THEN MAX(CASE WHEN IND='S' THEN DT END) END) OVER()
          ,MAX(DT)
          ) as DT
  FROM T
GROUP BY ID;

使用道具 举报

回复
论坛徽章:
13
2010新春纪念徽章
日期:2010-03-01 11:04:59技术图书徽章
日期:2018-03-01 10:21:49秀才
日期:2018-03-01 10:21:252015年新春福章
日期:2015-03-06 11:58:18喜羊羊
日期:2015-03-04 14:52:46优秀写手
日期:2014-04-22 06:00:18马上有对象
日期:2014-02-18 16:44:082014年新春福章
日期:2014-02-18 16:44:082013年新春福章
日期:2013-02-25 14:51:242012新春纪念徽章
日期:2012-01-04 11:56:01
 楼主| 发表于 2019-8-10 12:07 | 显示全部楼层
newkid 发表于 2019-8-9 10:52
WITH t     AS (SELECT 1 ID, 10 DT, 'S' IND FROM DUAL         UNION ALL         SELECT 1 ID, 20 DT, ' ...

知道你出手就不一样。厉害!👍👍👍

使用道具 举报

回复
论坛徽章:
13
2010新春纪念徽章
日期:2010-03-01 11:04:59技术图书徽章
日期:2018-03-01 10:21:49秀才
日期:2018-03-01 10:21:252015年新春福章
日期:2015-03-06 11:58:18喜羊羊
日期:2015-03-04 14:52:46优秀写手
日期:2014-04-22 06:00:18马上有对象
日期:2014-02-18 16:44:082014年新春福章
日期:2014-02-18 16:44:082013年新春福章
日期:2013-02-25 14:51:242012新春纪念徽章
日期:2012-01-04 11:56:01
 楼主| 发表于 2019-8-10 12:08 | 显示全部楼层
solomon_007 发表于 2019-8-9 00:07
没N,有一个N,有多个N , 3个例子:SQL> with t  2       as (select 1 id, 10 dt, 'S' ind from dual  3    ...

谢谢

使用道具 举报

回复
论坛徽章:
466
生肖徽章2007版:猴
日期:2008-05-16 11:28:59生肖徽章2007版:马
日期:2008-10-08 17:01:01SQL大赛参与纪念
日期:2011-04-13 12:08:17授权会员
日期:2011-06-17 16:14:53ITPUB元老
日期:2011-06-21 11:47:01ITPUB官方微博粉丝徽章
日期:2011-07-01 09:45:27ITPUB十周年纪念徽章
日期:2011-09-27 16:30:472012新春纪念徽章
日期:2012-01-04 11:51:22海蓝宝石
日期:2012-02-20 19:24:27铁扇公主
日期:2012-02-21 15:03:13
发表于 2019-8-10 15:11 | 显示全部楼层
newkid 发表于 2019-8-9 23:52
WITH t     AS (SELECT 1 ID, 10 DT, 'S' IND FROM DUAL         UNION ALL         SELECT 1 ID, 20 DT, ' ...

真优雅!

使用道具 举报

回复

您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

SACC2019中国系统架构师大会

【数字转型 架构演进】SACC2019中国系统架构师大会,7折限时优惠重磅来袭!
2019年10月31日~11月2日第11届中国系统架构师大会(SACC2019)将在北京隆重召开。四大主线并行的演讲模式,1个主会场、20个技术专场、超千人参与的会议规模,100+来自互联网、金融、制造业、电商等领域的嘉宾阵容,将为广大参会者提供一场最具价值的技术交流盛会。

限时七折期:2019年8月31日前


----------------------------------------

大会官网>>
TOP技术积分榜 社区积分榜 徽章 团队 统计 知识索引树 积分竞拍 文本模式 帮助
  ITPUB首页 | ITPUB论坛 | 数据库技术 | 企业信息化 | 开发技术 | 微软技术 | 软件工程与项目管理 | IBM技术园地 | 行业纵向讨论 | IT招聘 | IT文档
  ChinaUnix | ChinaUnix博客 | ChinaUnix论坛
CopyRight 1999-2011 itpub.net All Right Reserved. 北京盛拓优讯信息技术有限公司版权所有 联系我们 
京ICP备09055130号-4  北京市公安局海淀分局网监中心备案编号:11010802021510 广播电视节目制作经营许可证:编号(京)字第1149号
  
快速回复 返回顶部 返回列表