Get a query to list the records that are on and in between the start and the end values of a particular column for the same Id

后端 未结 2 1668
攒了一身酷
攒了一身酷 2021-01-24 16:21

There is a table with the columns :

USE \'table\';  
insert into person values   
(\'11\',\'xxx\',\'1976-05-10\',\'p1\'),  
(\'11\',\'xxx \',\'1976-06-11\',\'p1\         


        
相关标签:
2条回答
  • 2021-01-24 16:24

    This can be achived by:

    SELECT Id, PId,
           MIN(Start_Date) AS sdt,
           MAX(Start_Date) as edt,
           IF(`place` <> @var_place_prev, (@var_rank:= @var_rank + 1), @var_rank) AS rank,
           (@var_place_prev := `place`) AS `place`
    FROM person, (SELECT @var_rank := 0, @var_place_prev := "") dummy
    GROUP BY rank, Place;
    

    Example: SQLFiddle

    If you want records to be ordered by ID then:

    SELECT Id, PId,
           MIN(Start_Date) AS sdt,
           MAX(Start_Date) as edt,
           `place`
    FROM(
         SELECT Id, PId,
                Start_Date
                IF(`place` <> @var_place_prev,(@var_rank:= @var_rank + 1),@var_rank) AS rank,
                (@var_place_prev := `place`) AS `place`
         FROM person, (SELECT @var_rank := 0, @var_place_prev := "") dummy
         ORDER BY ID ASC
        ) a
    GROUP BY rank, Place;
    
    0 讨论(0)
  • 2021-01-24 16:46

    This isn't pretty, and performance might be horrible, but at least it works:

    select min(sdt), edt, place
    from (
      select A.Start_Date sdt, max(B.Start_Date) edt, A.place
      from person A
           inner join person B on A.place = B.place
                              and A.Start_Date <= B.Start_Date
           left join person C on A.place != C.place
                             and A.Start_Date < C.Start_Date
                             and C.Start_Date < B.Start_Date
      where C.place is null
      group by A.Start_Date, A.place
    ) X
    group by edt, place
    

    The idea is that A and B represent all pairs of rows. C will be any row in between these two which has a different place. So after the C.place is null restriction, we know that A and B belong to the same range, i.e. a group of rows for one place with no other place in between them in chronological order. From all these pairs, we want to identify those with maximal range, those which encompass all others. We do so using two nested group by queries. The inner one will choose the maximal end date for every possible start date, whereas the outer one will choose the minimal start date for every possible end date. The result are maximal ranges of chronologically subsequent rows describing the same place.

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