• 根据指定时间找出最接近的预约时间


    数据库环境:SQL SERVER 2008R2

    有用户表和预约时间表如下:

    用户表

    预约时间表

    要求得到如下结果

    有以下限制条件:

    1.有预约时间大于等于今天的,取最早的日期

    2.没有大于今天的预约时间,取过去预约时间最近的一条

    3.没有预约时间的,则预约时间显示为NULL

    初看题目时,觉得很简单,用分析函数整一下就OK了。但真正去实现的时候,发现并不是自己想象的那么简单。

    用分析函数整了一会,没有什么好的思路,就暂时把预约时间表分成2部分,一部分是预约时间大于等于今天的,

    另一部分则是预约时间小于今天。分别排序后用union all关联起来。

    1.建表,准备测试数据

    CREATE TABLE users (id INT,username VARCHAR(10))
    INSERT INTO users(id,username) VALUES(1,'张三')
    INSERT INTO users(id,username) VALUES(2,'李四')
    INSERT INTO users(id,username) VALUES(3,'王五')
    
    CREATE TABLE appointment(id INT,userid INT,ordertime DATE)
    INSERT INTO appointment(id,userid,ordertime)VALUES(1,1,'2015-07-30')
    INSERT INTO appointment(id,userid,ordertime)VALUES(2,1,'2015-07-23')
    INSERT INTO appointment(id,userid,ordertime)VALUES(3,2,'2015-07-26')
    INSERT INTO appointment(id,userid,ordertime)VALUES(4,1,'2015-07-31')
    INSERT INTO appointment(id,userid,ordertime)VALUES(5,2,'2015-07-21')
    View Code

    2.union all实现

    WITH    x0
              AS ( /*大于等于今天的预约时间分组取最小值*/ SELECT userid ,
                                                MIN(ordertime) ordertime
                                         FROM   dbo.appointment
                                         WHERE  ordertime >= GETDATE()
                                         GROUP BY userid
                   UNION ALL
                   /*小于今天的预约时间分组取最大值*/
                   SELECT   userid ,
                            MAX(ordertime) ordertime
                   FROM     dbo.appointment
                   WHERE    ordertime < GETDATE()
                   GROUP BY userid
                 ),/*合并之后可能会存在一个客户有2个预约时间段,将结果集分组取最大值*/
            x1
              AS ( SELECT   userid ,
                            MAX(ordertime) ordertime
                   FROM     x0
                   GROUP BY userid
                 )
        SELECT  u.username ,
                p.ordertime
        FROM    users u
                LEFT JOIN x1 p ON p.userid = u.id
    View Code

    再回来审了一下题,发觉自己钻进死胡同里头了。其实,通过case when比较预约时间和今天的大小,

    然后用group by分组求就行。

    3.case when+group by实现

    WITH    x0
              AS ( SELECT   userid ,
                            MAX(CASE WHEN ordertime < GETDATE() THEN ordertime
                                END) AS max_ordertime ,--早于今天,取预约时间最大值
                            MIN(CASE WHEN ordertime >= GETDATE() THEN ordertime
                                END) AS min_ordertime  --预约时间大于等于今天,取预约时间最小值
                   FROM     appointment
                   GROUP BY userid
                 )
        SELECT  a.username ,
                ISNULL(b.min_ordertime, b.max_ordertime) AS ordertime
        FROM    users a
                LEFT JOIN x0 b ON b.userid = a.id
    View Code

    绕来绕去,就这么简单!

  • 相关阅读:
    USACO6.4-The Primes
    ZOJ2112--Dynamic Rankings (动态区间第k大)
    Havel定理
    HDU5107---K-short Problem (线段树区间 合并、第k大)
    POJ2104-- K-th Number(主席树静态区间第k大)
    poj2409 & 2154 polya计数+欧拉函数优化
    CodeForces
    HDU
    HDU
    Gym
  • 原文地址:https://www.cnblogs.com/boss-he/p/4681125.html
Copyright © 2020-2023  润新知