Ordering parent rows by date descending with child rows ordered independently beneath each

偶尔善良 提交于 2021-01-27 12:44:58

问题


This is a contrived version of my table schema to illustrate my problem:

QuoteID, Details, DateCreated, ModelQuoteID

Where QuoteID is the primary key and ModelQuoteID is a nullable foreign key back onto this table to represent a quote which has been modelled off another quote (and may have subsequently had its Details column etc changed).

I need to return a list of quotes ordered by DateCreated descending with the exception of modelled quotes, which should sit beneath their parent quote, ordered by date descending within any other sibling quotes (quotes can only be modelled one level deep).

So for example if I have these 4 quote rows:

1, 'Fix the roof', '01/01/2012', null
2, 'Clean the drains', '02/02/2012', null
3, 'Fix the roof and door', '03/03/2012', 1
4, 'Fix the roof, door and window', '04/04/2012', 1
5, 'Mow the lawn', '05/05/2012', null

Then I need to get the results back in this order:

5 - Mow the lawn
2 - Clean the drains
1 - Fix the roof
4 - -> Fix the roof, door and window
3 - -> Fix the roof and door

I'm also passing in search criteria such as keywords for Details, and I'm returning modelled quotes even if they don't contain the search term but their parent quote does. I've got that part working using a common table expression to get the original quotes, unioned with a join for modelled ones.

That works nicely but currently I'm having to do the rearrangement of the modelled quotes into the correct order in code. That's not ideal because my next step is to implement paging in the SQL, and if the rows are not grouped properly at that time then I won't have the children present in the current page to do the re-ordering in code. Generally speaking they will be naturally grouped together anyway, but not always. You could create a model quote today for a quote from a month back.

I've spent quite some time on this, can any SQL gurus help? Much appreciated.

EDIT: Here is a contrived version of my SQL to fit my contrived example :-)

;with originals as (
select
    q.*
from
    Quote q
where
    Details like @details
)
select
    *
from
(
select
    o.*
from
    originals o

union

select
    q2.*
from
    Quote q2
join
    originals o on q2.ModelQuoteID = o.QuoteID
)
as combined

order by
    combined.CreatedDate desc

回答1:


Watching the Olympics -- just skimmed your post -- looks like you want to control the sort at each level (root and one level in), and make sure the data is returned with the children directly beneath its parent (so you can page the data...). We do this all the time. You can add an order by to each inner query and create a sort column. I contrived a slightly different example that should be easy for you to apply to your circumstance. I sorted the root ascending and level one descending just to illustrate how you can control each part.

declare @tbl table (id int, parent int, name varchar(10))

insert into @tbl (id, parent, name)
values (1, null, 'def'), (2, 1, 'this'), (3, 1, 'is'), (4, 1, 'a'), (5, 1, 'test'),
       (6, null, 'abc'), (7, 6, 'this'), (8, 6, 'is'), (9, 6, 'another'), (10, 6, 'test')

;with cte (id, parent, name, sort) as (
  select id, parent, name, cast(right('0000' + cast(row_number() over (order by name) as varchar(4)), 4) as varchar(1024))
  from   @tbl
  where  parent is null

  union all

  select t.id, t.parent, t.name, cast(cte.sort + right('0000' + cast(row_number() over (order by t.name desc) as varchar(4)), 4) as varchar(1024))
  from   @tbl t inner join cte on t.parent = cte.id
)
select * from cte
order by sort

This produces these results:

id    parent    name     sort
----  --------  -------  ----------
6     NULL      abc      0001
7     6         this     00010001
10    6         test     00010002
8     6         is       00010003
9     6         another  00010004
1     NULL      def      0002
2     1         this     00020001
5     1         test     00020002
3     1         is       00020003
4     1         a        00020004

You can see that the root nodes are sorted ascending and the inner nodes are sorted descending.



来源:https://stackoverflow.com/questions/11857295/ordering-parent-rows-by-date-descending-with-child-rows-ordered-independently-be

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!