none
求助~被一个奇怪的Sql语句问题问倒了~~ RRS feed

  • 问题

  • 今天一朋友问:
    有一张表T,有三个字段:BeginNum,EndNum,Time
    create table T(beginnum int,endnum int ,time datetime,check(endnum >=beginnum))
    估计有1W条数据左右
    他问:每条记录的beginnum 和endnum都看作包含(between)一组连续的自然数,那么某些自然数在所有的记录可能出现多次。那么:
     如何选择出这样一条记录,其满足:

    1 该记录包含出现几率最小的自然数,(同时附加选择出该自然数)
    2 该记录Time最小
    3 每次插入的时候,均需要计算出这样一条记录,所以效率要高

    我给他说改表结构:create table T(num int,time datetime)
    将所有记录拆分记录进来,比如1,2,time这样的记录我在T表中记录成2条记录:1,Time;2,Time
    然后建表T2 (num int,sum int),每次插入T表时,跟新T2表的统计记录。同时要解决123问题就方便了。
    结果被K。

    请教:1 如何不改表结构满足他的变态要求;2 可以改表结构,如何才好?
    (最好不改表结构)
    2009年4月3日 9:45

答案

  • 分拆方法很有用,可我这里没有分隔符,而是一个范围,怎么搞?
    (其实那个分拆方法我没看懂,回去慢慢消化)
    樓主要看這一段,或在存儲過程生成臨時表處理
    步驟1:生成一個自增表建上索引
    吳熹
    2009年4月6日 3:51
    版主
  • 如果出现2个自然数出现几率一样,事件有相同,选择那个?
    你的这个需求可以不需要修改表结构,需要一个临时表
    先找出Min(beginNum)和Max(endNum),确定自然数边界,然后循环,使用冒泡的方法找到最小值,如果出现相同几率的,则记录在临时表中,最后通过值来去找到时间

    详细的语句过节后再写

    如果几率一样,选择Time最小的那个。Time是唯一的,表结构中该字段忘记了+唯一约束,Sorry

    找出边界后循环找到最小值,这个计算量估计有点大。。。。

    计算量大没办法,但是除了这种循环就只能拆分,1 billion的计算量和1 billion的存储容量只能你自己来平衡了
    拆分出来的结果也不一定很小,你可以先看看sum(endtime)-sun(begintime)的差是多少,如果很大那就循环好一些,如果不大可以考虑拆分。
    2009年4月6日 14:29

全部回复

  • 最简单的方法就是借助中间的临时表来解决来模拟拆分的过程,当然这种方法不是很好,但是很有效
    2009年4月3日 10:15
  • 今天一朋友问:
    有一张表T,有三个字段:BeginNum,EndNum,Time
    create table T(beginnum int,endnum int ,time datetime,check(endnum >=beginnum))
    估计有1W条数据左右
    他问:每条记录的beginnum 和endnum都看作包含(between)一组连续的自然数,那么某些自然数在所有的记录可能出现多次。那么:
     如何选择出这样一条记录,其满足:

    1 该记录包含出现几率最小的自然数,(同时附加选择出该自然数)
    2 该记录Time最小
    3 每次插入的时候,均需要计算出这样一条记录,所以效率要高

    我给他说改表结构:create table T(num int,time datetime)
    将所有记录拆分记录进来,比如1,2,time这样的记录我在T表中记录成2条记录:1,Time;2,Time
    然后建表T2 (num int,sum int),每次插入T表时,跟新T2表的统计记录。同时要解决123问题就方便了。
    结果被K。

    请教:1 如何不改表结构满足他的变态要求;2 可以改表结构,如何才好?
    (最好不改表结构)
    經常調用時;
    方法步驟:
    1、生成一個自增表建上索引
    2、再利用這個表分拆
    分拆方法參照


    吳熹
    2009年4月3日 10:23
    版主
  • 如果出现2个自然数出现几率一样,事件有相同,选择那个?
    你的这个需求可以不需要修改表结构,需要一个临时表
    先找出Min(beginNum)和Max(endNum),确定自然数边界,然后循环,使用冒泡的方法找到最小值,如果出现相同几率的,则记录在临时表中,最后通过值来去找到时间

    详细的语句过节后再写
    2009年4月4日 13:02
  • 今天一朋友问:
    有一张表T,有三个字段:BeginNum,EndNum,Time
    create table T(beginnum int,endnum int ,time datetime,check(endnum >=beginnum))
    估计有1W条数据左右
    他问:每条记录的beginnum 和endnum都看作包含(between)一组连续的自然数,那么某些自然数在所有的记录可能出现多次。那么:
     如何选择出这样一条记录,其满足:

    1 该记录包含出现几率最小的自然数,(同时附加选择出该自然数)
    2 该记录Time最小
    3 每次插入的时候,均需要计算出这样一条记录,所以效率要高

    我给他说改表结构:create table T(num int,time datetime)
    将所有记录拆分记录进来,比如1,2,time这样的记录我在T表中记录成2条记录:1,Time;2,Time
    然后建表T2 (num int,sum int),每次插入T表时,跟新T2表的统计记录。同时要解决123问题就方便了。
    结果被K。

    请教:1 如何不改表结构满足他的变态要求;2 可以改表结构,如何才好?
    (最好不改表结构)
    經常調用時;
    方法步驟:
    1、生成一個自增表建上索引
    2、再利用這個表分拆
    分拆方法參照


    吳熹
    这个方法有点问题,如果说有2条记录,
    beginNum,endNum,time
    1,1 billion
    1,2 billion
    这样岂不是要插入3billion的记录数?插入数据的成本也太高了。
    2009年4月4日 13:04
  • 如果出现2个自然数出现几率一样,事件有相同,选择那个?
    你的这个需求可以不需要修改表结构,需要一个临时表
    先找出Min(beginNum)和Max(endNum),确定自然数边界,然后循环,使用冒泡的方法找到最小值,如果出现相同几率的,则记录在临时表中,最后通过值来去找到时间

    详细的语句过节后再写

    如果几率一样,选择Time最小的那个。Time是唯一的,表结构中该字段忘记了+唯一约束,Sorry

    找出边界后循环找到最小值,这个计算量估计有点大。。。。
    2009年4月5日 13:18
  • 今天一朋友问:
    有一张表T,有三个字段:BeginNum,EndNum,Time
    create table T(beginnum int,endnum int ,time datetime,check(endnum >=beginnum))
    估计有1W条数据左右
    他问:每条记录的beginnum 和endnum都看作包含(between)一组连续的自然数,那么某些自然数在所有的记录可能出现多次。那么:
     如何选择出这样一条记录,其满足:

    1 该记录包含出现几率最小的自然数,(同时附加选择出该自然数)
    2 该记录Time最小
    3 每次插入的时候,均需要计算出这样一条记录,所以效率要高

    我给他说改表结构:create table T(num int,time datetime)
    将所有记录拆分记录进来,比如1,2,time这样的记录我在T表中记录成2条记录:1,Time;2,Time
    然后建表T2 (num int,sum int),每次插入T表时,跟新T2表的统计记录。同时要解决123问题就方便了。
    结果被K。

    请教:1 如何不改表结构满足他的变态要求;2 可以改表结构,如何才好?
    (最好不改表结构)
    經常調用時;
    方法步驟:
    1、生成一個自增表建上索引
    2、再利用這個表分拆
    分拆方法參照


    吳熹
    分拆方法很有用,可我这里没有分隔符,而是一个范围,怎么搞?
    (其实那个分拆方法我没看懂,回去慢慢消化)
    2009年4月5日 13:25
  • 分拆方法很有用,可我这里没有分隔符,而是一个范围,怎么搞?
    (其实那个分拆方法我没看懂,回去慢慢消化)
    樓主要看這一段,或在存儲過程生成臨時表處理
    步驟1:生成一個自增表建上索引
    吳熹
    2009年4月6日 3:51
    版主
  • 如果出现2个自然数出现几率一样,事件有相同,选择那个?
    你的这个需求可以不需要修改表结构,需要一个临时表
    先找出Min(beginNum)和Max(endNum),确定自然数边界,然后循环,使用冒泡的方法找到最小值,如果出现相同几率的,则记录在临时表中,最后通过值来去找到时间

    详细的语句过节后再写

    如果几率一样,选择Time最小的那个。Time是唯一的,表结构中该字段忘记了+唯一约束,Sorry

    找出边界后循环找到最小值,这个计算量估计有点大。。。。

    计算量大没办法,但是除了这种循环就只能拆分,1 billion的计算量和1 billion的存储容量只能你自己来平衡了
    拆分出来的结果也不一定很小,你可以先看看sum(endtime)-sun(begintime)的差是多少,如果很大那就循环好一些,如果不大可以考虑拆分。
    2009年4月6日 14:29
  • 十分感谢2位解答,假放完了,继续问:
    如果Begin、End纪录的不是自然数,那理论上也可以找到这样一个出现次数最少的数值(范围)。
    而分拆、循环就不好用了。
    那该怎么算呢?

    有一个游客使用游泳池纪录:
    Id       BeginTime                        EndTime
    1        2003-4-2 12:3:4                2003-4-2 12:3:4
    2        2003-4-3   2:3:4                2003-4-12 2:3:4
    3        2003-3-2 12:3:4                2003-4-2 12:3:4
    4        2003-4-2 12:3:4                2003-5-2 12:3:4
    5        2002-4-2 12:3:4                2003-4-2 5:3:4
    6        2003-4-2 14:3:4                2009-4-2 17:3:4
    .......(数据乱输入的,保证Begintime<EndTime就行了)
    要得到:1 游泳池有人使用,但是使用人数最少的时间段;2 游泳池使用人数最多的时间段。
    注意:结构有可能是多个时间段。

    2009年4月7日 4:41