最近做的一个财物管理系统中查询过期或逾期的存储过程,返回 “财物所属的案件名称”,“财物名称”,“财物编号”,“过期或逾期时间”(超期或逾期前7天开始预警)。
遇到“union all 内不能使用 order by”的问题,百度了很久,都没有一个找到一个好的解决方案。最终还是自己实现了,记录一下。
 
为什么用存储过程,非得用union all 而不在程序中拼接表数据?
        这个存储过程不是供我们Web程序使用的,它是提供给运行在服务器上的C/S程序调用(用来投放到机房外的LED显示屏)。
因为这个C/S程序不是我们写的,别人要求用存储过程并一次性返回超期和预期的数据。
当时我正在客户那里安装这个系统,这个功能是客户临时加的,所以就匆忙赶了一个,当时没排序,回来后整理时才遇到这个问题。
涉及到的数据库表(字段):
 案件表【AnJian】:(Id,案件名称【anjianmingcheng】)
财物表【CaiWu 】:(Id,所属案件【Id]anjianId】,财物编号【caiwubianhao】,财物名称【caiwumingcheng】,保存指定的保存结束时间【caoqi】)
财物调用记录表【CaiWuDiaoYongJiLu 】:(Id,被调用财物Id【caiwuId】,调用时指定的归还时间【yujingTime】)
注 保存结束时间和调用归还时间不能为空,如果是长期会在程序中指定一个超大的时间值(9999/12/30)。
 
最初版本:
 ALTER proc [dbo].[pr_get_time_limit]

 as

 select
cast(a.anjianmingcheng as varchar(100)) as anjianmingcheng,
cast(c.caiwumingcheng as varchar(100)) as caiwumingcheng,
cast(c.caiwubianhao as varchar(100)) as caiwubianhao,
case
when datediff(day,c.caoqi,getdate())> 0 then '保存超期'+cast(abs(datediff(day,c.caoqi,getdate())) as varchar(50))+'天'
else cast(abs(datediff(day,c.caoqi,getdate())) as varchar(50))+'天后保存超期'
end as state,
c.caoqi as tagtime
from SACW_CaiWu c
left join SACW_CaiWuDiaoYongJiLu as d on c.Id=d.caiwuId
left join SACW_AnJian as a on c.anjianId=a.id
where c.jiazhijine>0 and getdate()>dateadd(day,-7,c.caoqi) or c.kucunshuliang>0 and getdate()>dateadd(day,-7,c.caoqi) union all select
cast(a.anjianmingcheng as varchar(100)) as anjianmingcheng,
cast(c.caiwumingcheng as varchar(100)) as caiwumingcheng,
cast(c.caiwubianhao as varchar(100)) as caiwubianhao,
case
when datediff(day,d.yujingTime,getdate())> 0 then '归还逾期'+cast(abs(datediff(day,d.yujingTime,getdate())) as varchar(50))+'天'
else cast(abs(datediff(day,d.yujingTime,getdate())) as varchar(50))+'天后归还逾期'
end as state,
d.yujingTime as tagtime
from SACW_CaiWuDiaoYongJiLu d
left join SACW_CaiWu c on c.Id=d.caiwuId
left join SACW_AnJian as a on c.anjianId=a.id
where d.jiazhijine>0 and getdate()> dateadd(day,-7,d.yujingTime) or d.caiwushuliang>0 and getdate()>dateadd(day,-7,d.yujingTime)
优化后的代码:
 ALTER proc [dbo].[pr_get_time_limit]

 as

 DECLARE @TempTime  datetime
SET @TempTime = DATEADD(DAY,7,GETDATE()) SELECT
a.anjianmingcheng as [anjianmingcheng],
t.cm as [caiwumingcheng],
t.cb as [caiwubianhao],
t.tagtime as [tagtime],
case
when t.orderby = 0 then
case
when t.timeSpan > 0 then '调用逾期'+cast(t.timeSpan as varchar(50))+'天'
--when t.timeSpan = 0 then '即将逾期'
else cast(abs(t.timeSpan) as varchar(50))+'天后调用逾期'
end
else
case
when t.timeSpan > 0 then '保存超期'+cast(t.timeSpan as varchar(50))+'天'
--when t.timeSpan = 0 then '即将超期'
else cast(abs(t.timeSpan) as varchar(50))+'天后保存超期'
end
end as [state] FROM (
select
c.anjianId as aid,
cast(c.caiwumingcheng as varchar(100)) as cm,
cast(c.caiwubianhao as varchar(100)) as cb,
datediff(day,d.yujingTime,getdate()) as timeSpan,
d.yujingTime as tagtime,
0 as orderby
from SACW_CaiWuDiaoYongJiLu d
left join SACW_CaiWu c on c.Id=d.caiwuId
where (d.jiazhijine>0 or d.caiwushuliang>0) and @TempTime > d.yujingTime union all select
c.anjianId as aid,
cast(c.caiwumingcheng as varchar(100)) as cm,
cast(c.caiwubianhao as varchar(100)) as cb,
datediff(day,c.caoqi,getdate()) as timeSpan,
c.caoqi as tagtime,
1 as orderby
from SACW_CaiWu c
where (c.jiazhijine>0 or c.kucunshuliang>0) and @TempTime > c.caoqi
) as t
left join SACW_AnJian as a on t.aid=a.id
order by t.orderby,t.timeSpan
问题,最初版本中的代码中datediff函数计算值怎样用一个临时变量存起来供后面使用,而不是重新计算。不知道这样写在存储过程中会不会有性能损失(理论上的)。
 
网上其它相关解决方案:
关于union all中使用多个order by 子句引起的问题 
 
UNION ALL 子句不能包含ORDER BY的解决之道
 
union all和order by一起使用出问题
 
order by 和union all 如何共存
 

SQL 语句中union all和order by同时使用的更多相关文章

  1. 【转载】SQL语句中Union和Union All的区别

    在使用到SQL语句进行数据库查询的过程中,如果需要求两个数据集合的并集,一般会使用到联合查询关键字Union或者Union All,其实Union和Union All两者的使用有一定差别,查出来的数据 ...

  2. (转载)SQL语句中Group by语句的详细介绍

    转自:http://blog.163.com/yuer_d/blog/static/76761152201010203719835 SQL语句中Group by语句的详细介绍              ...

  3. Mybatis中动态SQL语句中的parameterType不同数据类型的用法

    Mybatis中动态SQL语句中的parameterType不同数据类型的用法1. 简单数据类型,    此时#{id,jdbcType=INTEGER}中id可以取任意名字如#{a,jdbcType ...

  4. 向已写好的多行插入sql语句中添加字段和值

    #region 添加支款方式--向已写好的多行插入sql语句中添加字段和值 public int A_ZhifuFS(int diqu) { ; string strData = @"SEL ...

  5. sql 语句中使用条件判断case then else end

    sql 语句中使用条件判断case then else end范例: SELECT les.[nLessonNo] FROM BS_Lesson AS les WHERE les.[sClassCod ...

  6. sql语句中获取datetime任何部分

    sql语句中获取datetime的日期部分 sql语句中 经常操作操作datetime类型数据.今天在写一个存储过程的时候需要将 一个datetime的值的 日期部分提取出来.网上有许多这方面的介绍. ...

  7. sql语句:union

     sql语句中,join,left join中,是将两个或多个表横向连接,而有时,我们需要将几个表或1个表纵向连接,甚至是连接自身,就比如,某些数据库脚本特别不合理的时候,但我们又不能说啥 ....郁 ...

  8. SQL语句中的乘号

    在ADO中,我们需要在SQL语句中使用乘法运算,可是添加'*'以后执行程序总是会出错,这是因为‘*’与sql中的‘*’关键字重合了,所以编译会出错. 解决办法:将乘法运算放到sql语句外面,将结果放入 ...

  9. LINQ to SQL语句之Union All/Union/Intersect和Top/Bottom和Paging和SqlMethods

    我们继续讲解LINQ to SQL语句,这篇我们来讨论Union All/Union/Intersect操作和Top/Bottom操作和Paging操作和SqlMethods操作 . Union Al ...

随机推荐

  1. 我的github代码库

    我的github代码库地址:https://github.com/gooree.Enjoy coding,enjoy sharing.

  2. Amazon Resource Names (ARNs)

    The following are the general formats for ARNs; the specific components and values used depend on th ...

  3. java代码中获取classpath路径

    Javaweb工程中,有时候需要自己手动的去读取classpath下面的配置文件,这里总结一点读取classpath路径的方法,分享一下. 方法一: String path = Test.class. ...

  4. js二级导航下拉菜单

    <!DOCTYPE html> <html> <head> <title>导航列表</title> <meta http-equiv= ...

  5. 织梦cms、帝国cms、PHPcms优缺点解析

    php才是建站的主流,cms这类程序又是用的最多的,占据主流的cms主要就是织梦,帝国,phpcms这三种的,这三个程序都是开源程序.国内用户众多.   一.从美观性来说(以官方默认模版为准   ph ...

  6. day9---paramiko ssh ftp

    安装 paramiko模块 win下: 进入到\Python35\Scripts> 执行:pip install paramiko Linux: 先升级下pip : pip3.5 install ...

  7. xml笔记

    <?xml version="1.0" encoding="UTF-8"?> ----------------------------------- ...

  8. win2003、win7下操作注册表

    在win2007里,web程序仅对LOCAL_CURRENT_USER能进行读(写:没有进行测试)操作. 在本地的IIS里运行的web程序,如需访问注册表,需要将对应的应用程序池中的标识里面的用户,改 ...

  9. Quartz.net2.2初体验

    简介:Quartz.net是一个开源的作用调度框架,非常强大,能够通过简单的配置帮助我们定时具体的操作.相对于我们用的线程里面while(true)然后sleep来执行某个操作,应该算的上是高端,大气 ...

  10. Java语法糖1:可变长度参数以及foreach循环原理

    语法糖 接下来几篇文章要开启一个Java语法糖系列,所以首先讲讲什么是语法糖.语法糖是一种几乎每种语言或多或少都提供过的一些方便程序员开发代码的语法,它只是编译器实现的一些小把戏罢了,编译期间以特定的 ...