3

这是我的表模式的人为版本来说明我的问题:

QuoteID、详细信息、DateCreated、ModelQuoteID

其中 QuoteID 是主键,ModelQuoteID 是返回到此表的可空外键,以表示已根据另一个报价建模的报价(并且可能随后更改了其详细信息列等)。

我需要返回一个按 DateCreated 降序排序的引号列表,但建模引号除外,它应位于其父引号下方,按日期在任何其他同级引号内降序排序(引号只能建模一层深度)。

因此,例如,如果我有这 4 个引号行:

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

然后我需要按以下顺序取回结果:

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

我还传递了搜索条件,例如详细信息的关键字,并且即使它们不包含搜索词但它们的父引号包含,我也会返回建模的引号。我已经使用公用表表达式使该部分工作以获取原始报价,并与建模的联接结合在一起。

这很好用,但目前我必须将建模的引号重新排列为代码中的正确顺序。这并不理想,因为我的下一步是在 SQL 中实现分页,如果当时行没有正确分组,那么我不会让当前页面中的子项在代码中进行重新排序。一般来说,无论如何它们都会自然地组合在一起,但并非总是如此。您今天可以为一个月前的报价创建模型报价。

我在这方面花了很多时间,任何 SQL 专家都可以帮忙吗?非常感激。

编辑:这是我的 SQL 的人为版本,以适合我的人为示例 :-)

;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
4

1 回答 1

4

观看奥运会 - 只是浏览了你的帖子 - 看起来你想控制每一层的排序(根和一层),并确保返回的数据是直接在其父级下方的子级(这样你就可以分页数据...)。我们一直这样做。您可以order by向每个内部查询添加一个并创建一个sort列。我设计了一个稍微不同的示例,您应该很容易将其应用于您的情况。我将根升序和一级降序排序只是为了说明如何控制每个部分。

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

这会产生以下结果:

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

可以看到根节点按升序排序,内部节点按降序排序。

于 2012-08-08T04:58:50.987 回答