最近做的一个财物管理系统中查询过期或逾期的存储过程,返回 “财物所属的案件名称”,“财物名称”,“财物编号”,“过期或逾期时间”(超期或逾期前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. DECLARE_GLOBAL_DATA_PTR宏定义问题

    最近闲着顺便看了看6410的uboot代码,因为友善的boot对nand部分代码做了隐藏,所以干脆找了光盘里面三星原厂的uboot代码来看,因为友善的boot代码肯定也是基于厂商的代码改的,肯定可以的 ...

  2. vim中输入tab符

    今天在写Makefile时各种出错.后来发现是all:的下一行,make前面必须是tab符,不能是空格. 但是vim中只要按tab就会自动转换成4个空格.平时编程需要,也不便把这个设置取消. 查了下, ...

  3. [置顶]PADS PCB功能使用技巧系列之NO.006- 如何实现OrCAD与PADS Layout同步?

    很多同仁都喜欢用OrCAD画原理图,而PCB Layout则用PADS/PowerPCB,这两者被有些人誉为“黄金组合”,但由于两者并非一套软件,因此如何实现同步亦是需要急待解决的问题... (未完待 ...

  4. eclipse执行上一次结果

    eclipse执行上一次结果,解决方法:Project-clean

  5. cobbler配置

    :ks脚本关闭pxe,这样就不会重复安装 sed -i 's/pxe_just_once: 0/pxe_just_once: 1/g' /etc/cobbler/settings 6:TFTP服务器 ...

  6. PyCharm 3.0 发布,提供免费开源版本

    PyCharm 发布最新的 3.0 版本,该版本新特性详见: http://www.jetbrains.com/pycharm/whatsnew/index.html 该版本最主要的是提供了免费开源的 ...

  7. 【视频教程】使用UIAutomation开发软件外挂

    UIAutomation是.Net 3.5之后提供的“界面自动化测试”技术,本来是给测试人员用的,不过UIAutomation由于也是界面自动操作的技术,比直接使用keybd_event.GetWin ...

  8. Yii2中的环境配置

    默认的Debug配置 在入口文件中 defined ( 'YII_DEBUG' ) or define ( 'YII_DEBUG', true ); defined ( 'YII_ENV' ) or ...

  9. 在Nifi 里 把 HDFS Json 为csv 格式

    import org.apache.commons.io.IOUtilsimport java.nio.charset.*import java.text.SimpleDateFormatimport ...

  10. Wix 安装部署教程(十四) -- 多语言安装包之用户许可协议

    在上一篇中,留下了许可协议的问题,目前已经解决.感谢网友武全的指点! 问题 一般我们是用WixVariable 来设定许可协议.如下所示: <WixVariable Id="WixUI ...