楼主: junsansi

[精华] 单条SQL语句实现复杂逻辑几例~~

[复制链接]
论坛徽章:
4
授权会员
日期:2008-10-22 16:57:012010新春纪念徽章
日期:2010-03-01 11:20:072011新春纪念徽章
日期:2011-02-18 11:43:35优秀写手
日期:2013-12-18 09:29:14
41#
发表于 2008-7-6 18:46 | 只看该作者
MODEL挺有意思的

使用道具 举报

回复
论坛徽章:
0
42#
发表于 2008-7-7 10:07 | 只看该作者
不错,收藏下来,留待后用!

使用道具 举报

回复
论坛徽章:
0
43#
发表于 2008-7-7 19:03 | 只看该作者
不错,学习学习!

使用道具 举报

回复
论坛徽章:
3
CTO参与奖
日期:2009-01-15 11:42:462010新春纪念徽章
日期:2010-01-04 08:33:08ITPUB十周年纪念徽章
日期:2011-11-01 16:24:04
44#
发表于 2008-11-3 20:26 | 只看该作者

第1题也可以用下面的办法解决,不需要用SQL Model

select city,product,year,sales
from tmp1
union
select city,product, 2002 year, sum(sales) sales
from tmp1
where product='彩电' and year in (2000,2001)
group by city,product
union
select city,product,2002 year, sum(sales) sales
from tmp1
where product='微波炉' and year=2000
group by city,product
union
select city,'彩电+微波炉' product,2002 year, sum(sales) sales
from tmp1
where (product='彩电' and year in (2000,2001))or(product='微波炉' and year=2000)
group by city
order by 1,2,3
/

使用道具 举报

回复
论坛徽章:
3
CTO参与奖
日期:2009-01-15 11:42:462010新春纪念徽章
日期:2010-01-04 08:33:08ITPUB十周年纪念徽章
日期:2011-11-01 16:24:04
45#
发表于 2008-11-3 22:03 | 只看该作者

第3题可以去除重复的月份,算法如下:


  1. CHENCH@lilac> l
  2.   1  SELECT id,station,
  3.   2                 p_start_date,
  4.   3                 NVL(p_end_date, p_start_date) p_end_date,
  5.   4                 start_date,
  6.   5                 END_date,
  7.   6                 CASE
  8.   7                   when p_end_date is null or p_end_date <= start_date THEN
  9.   8                    MONTHS_BETWEEN(end_date, start_date)
  10.   9                   WHEN end_date <= p_end_date THEN
  11. 10                    0
  12. 11                   WHEN start_date <= p_end_date THEN
  13. 12                    MONTHS_BETWEEN(end_date, p_end_date)
  14. 13                 END months
  15. 14            FROM (select id,station,
  16. 15                         lag(start_date, 1, start_date) over(order by start_date) p_start_date,
  17. 16                         max(end_date) over(order by start_date rows between unbounded preceding
  18. and 1 preceding) p_end_date,
  19. 17                         start_date,
  20. 18                         end_date
  21. 19                    from tmp3)
  22. 20* order by start_date
  23. CHENCH@lilac> /

  24.         ID STATION              P_START_DATE P_END_DATE   START_DATE   END_DATE         MONTHS
  25. ---------- -------------------- ------------ ------------ ------------ ------------ ----------
  26.       1000 开发                 01-JAN-00    01-JAN-00    01-JAN-00    01-APR-00             3
  27.       1000 DBA                  01-JAN-00    01-APR-00    01-FEB-00    01-MAR-00             0
  28.       1000 兼职经理             01-FEB-00    01-APR-00    01-MAR-00    01-AUG-00             4
  29.       1000 测试                 01-MAR-00    01-AUG-00    01-JUL-00    01-OCT-00             2
  30.       1000 副经理               01-JUL-00    01-OCT-00    01-JAN-01    01-APR-01             3
  31.       1000 经理                 01-JAN-01    01-APR-01    01-MAY-01    01-AUG-01             3

  32. 6 rows selected.

  33. Elapsed: 00:00:00.84

复制代码

最后一列为不重复工作月数,累加即为总工作月数:15个月。

[ 本帖最后由 addm 于 2008-12-5 11:26 编辑 ]

使用道具 举报

回复
论坛徽章:
3
CTO参与奖
日期:2009-01-15 11:42:462010新春纪念徽章
日期:2010-01-04 08:33:08ITPUB十周年纪念徽章
日期:2011-11-01 16:24:04
46#
发表于 2008-11-3 22:16 | 只看该作者

第4题可以简化如下:

select adddate,max(addvalue) over (partition by addvalue_c) addvalue
from (
select adddate,addvalue,
sum(addvalue) over (order by adddate rows between current row and unbounded following) addvalue_c
from tmp4
)
order by adddate
/

CHENCH@lilac> /

ADDDATE                ADDVALUE
-------------------- ----------
2007-03-01                 3.64
2007-03-02                 3.64
2007-03-05                 3.64
2007-03-06                 3.82
2007-03-07                 3.47
2007-03-08                 3.47
2007-03-09                 4.01
2007-03-12                 4.01
2007-03-13                 4.01
2007-03-14                 4.21
2007-03-15                 4.12

ADDDATE                ADDVALUE
-------------------- ----------
2007-03-16                    0
2007-03-17                    0

13 rows selected.

Elapsed: 00:00:01.21

使用道具 举报

回复
论坛徽章:
520
奥运会纪念徽章:垒球
日期: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
47#
发表于 2008-11-4 05:29 | 只看该作者
原帖由 addm 于 2008-11-3 22:03 发表
CHENCH@lilac> l
  1  SELECT id,station,
  2                 p_start_date,
  3                 NVL(p_end_date, p_start_date) p_end_date,
  4                 start_date,
  5                 END_date,
  6                 CASE
  7                   when p_end_date is null or p_end_date  


这位兄弟的SQL写得真不错,但如果我加入这么一条数据就会出问题:
insert into tmp3 (ID, STATION, START_DATE, END_DATE)
values ('1000', 'QA LEAD', to_date('01-01-2000', 'dd-mm-yyyy'), to_date('01-03-2000', 'dd-mm-yyyy'));

修改一下:
SELECT id,station,
       p_end_date,
       start_date,
       END_date,
       CASE
         when p_end_date is null or p_end_date <= start_date THEN
              MONTHS_BETWEEN(end_date, start_date)
         WHEN end_date <= p_end_date THEN
              0
        WHEN start_date <= p_end_date THEN
              MONTHS_BETWEEN(end_date, p_end_date)
       END months
  FROM (select id,station,
               max(end_date) over(PARTITION BY id order by start_date,end_date DESC ROWS between unbounded preceding and 1 preceding) p_end_date,
               start_date,
               end_date
          from tmp3
        )
order by start_date
/


第四题的写法很是巧妙,我钻个牛角尖,如果addvalue有正数负数就不行了, 因为addvalue_c已经不往一个方向变化

[ 本帖最后由 newkid 于 2008-11-4 05:35 编辑 ]

使用道具 举报

回复
论坛徽章:
0
48#
发表于 2008-11-4 08:28 | 只看该作者
好难理解对于初学的我来说 呵呵

使用道具 举报

回复
论坛徽章:
3
CTO参与奖
日期:2009-01-15 11:42:462010新春纪念徽章
日期:2010-01-04 08:33:08ITPUB十周年纪念徽章
日期:2011-11-01 16:24:04
49#
发表于 2008-11-4 09:40 | 只看该作者
原帖由 newkid 于 2008-11-4 05:29 发表


这位兄弟的SQL写得真不错,但如果我加入这么一条数据就会出问题:
insert into tmp3 (ID, STATION, START_DATE, END_DATE)
values ('1000', 'QA LEAD', to_date('01-01-2000', 'dd-mm-yyyy'), to_date('01-03-2000', 'dd-mm-yyyy'));



我试了,添加你的数据,没有错啊。

SELECT id,
       station,
       p_start_date,
       NVL(p_end_date, p_start_date) p_end_date,
       start_date,
       END_date,
       CASE
         when p_end_date is null or p_end_date <= start_date THEN
          MONTHS_BETWEEN(end_date, start_date)
         WHEN end_date <= p_end_date THEN
          0
         WHEN start_date <= p_end_date THEN
          MONTHS_BETWEEN(end_date, p_end_date)
       END months
  FROM (select id,
               station,
               lag(start_date, 1, start_date) over(order by start_date) p_start_date,
               max(end_date) over(order by start_date rows between unbounded preceding and 1 preceding) p_end_date,
               start_date,
               end_date
          from tmp3)
order by start_date;

        ID STATION              P_START_DATE P_END_DATE   START_DATE   END_DATE         MONTHS
---------- -------------------- ------------ ------------ ------------ ------------ ----------
      1000 QA LEAD              01-JAN-00    01-JAN-00    01-JAN-00    01-MAR-00             2
      1000 开发                 01-JAN-00    01-MAR-00    01-JAN-00    01-APR-00             1
      1000 DBA                  01-JAN-00    01-APR-00    01-FEB-00    01-MAR-00             0
      1000 兼职经理             01-FEB-00    01-APR-00    01-MAR-00    01-AUG-00             4
      1000 测试                 01-MAR-00    01-AUG-00    01-JUL-00    01-OCT-00             2
      1000 副经理               01-JUL-00    01-OCT-00    01-JAN-01    01-APR-01             3
      1000 经理                 01-JAN-01    01-APR-01    01-MAY-01    01-AUG-01             3

7 rows selected.

Elapsed: 00:00:00.20

还是15个月。不知你说的错误,是什么?

========
题外话:另外,看样子这位老兄也是oracle业内资深人士。小弟我以前做c++游戏开发,精通数据结构、常用算法、c++程序设计。(本来也不敢妄称精通,不过在上海做了几家业内小有名气的游戏公司,发现所谓的高手也不过如此,遂抖胆自诩精通。另外,对目前游戏开发混乱的现状,略有失望,决心转行oracle数据库。)今年才转oracle数据库,主攻oracle开发,对oracle基于成本的优化,有较多研究。目前在一家中型民营企业做小头目,带七、八个新人。
小弟想找家大型的专做oracle相关开发的公司,一直未能如愿。主要是oracle相关职位需求较少,一般招的也是初级职位。也不知哪家大公司招中、高级的oracle开发职位。
这位老兄,如果知道相关职位信息,帮忙引见一下。多谢了啊!

使用道具 举报

回复
论坛徽章:
4
生肖徽章2007版:鸡
日期:2008-11-25 11:41:15生肖徽章2007版:虎
日期:2009-02-16 09:27:232010年世界杯参赛球队:德国
日期:2010-03-02 14:48:342013年新春福章
日期:2013-02-25 14:51:24
50#
发表于 2008-11-4 10:27 | 只看该作者
总结的好

使用道具 举报

回复

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

本版积分规则 发表回复

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