Sliding certain records to the end of a run of the same date

前端 未结 3 1997
名媛妹妹
名媛妹妹 2021-01-26 10:59

I have three columns -

  • TheDate - Obviously a date.
  • TheID - A strictly increasing ID.
  • TheType - A Record t
相关标签:
3条回答
  • 2021-01-26 11:26

    This is complicated. First you must find consecutive date records, so with

    thedate     theid  thetype
    2014-07-12   5001       59
    2014-07-12   5002      101
    2014-07-12   5003       88
    2014-07-13   5004       10
    2014-07-12   5005       60
    

    you would identify 2014-07-12 as one occurrence for the first three records and another for the last record. The second record would have to get position #3 in your results, not #5.

    You achieve this by giving consecutive records a group key by using first LAG to look into the previous record, thus creating a flag on group change, and then cumulating these flags.

    select thedate, theid, thetype
    from
    (
      select 
        thedate, theid, thetype,
        sum(new_group) over (order by theid) as group_key
      from
      (
        select
          thedate, theid, thetype,
          case when lag(thedate) over (order by theid) = thedate then 0 else 1 as new_group
        from mytable
      ) marked
    ) grouped
    order by 
      group_key,
      case when thetype = 101 then 1 else 0 end,
      theid;
    
    0 讨论(0)
  • 2021-01-26 11:33

    If TheID cannot be null then just change the TheID to null as part of the order by where TheType is a special value:

    order by TheDate, 
             case TheType
               when 101 then null
               else TheID
             end nulls last
    
    0 讨论(0)
  • 2021-01-26 11:35

    Taking the liberty granted in comments to assume that TheDate is non-decreasing with ascending TheId, if r1.TheId < r2.TheId then it must be the case that r1.TheDate <= r2.TheDate (that's the definition of non-decreasing). In that case, ordering first by TheDate and then by TheId produces the same order as ordering by TheId alone. Looking at it from the other direction, ordering by TheId automatically produces results clustered by TheDate and in order by date.

    But what you're already doing differs from ordering by (TheDate, TheId) (which we already established is the same as ordering by just TheId) only by moving the special records to the end of each date cluster, which is exactly what you say you want. Thus, you must be getting your results in the desired order; if you in fact have any problem then it must be that you are dissatisfied with the means by which you are doing so. For instance, perhaps you are concerned with query performance.

    If your existing ordering indeed produces the correct results, however, then I'm having trouble seeing an alternative that I would expect to deliver substantially better performance. No doubt the ordering can be produced by means that do not rely on TheDate to be non-decreasing, but I would expect all of those to be comparatively expensive to compute.

    0 讨论(0)
提交回复
热议问题