SQL Server 中的自定义排序

Posted

技术标签:

【中文标题】SQL Server 中的自定义排序【英文标题】:Custom sort in SQL Server 【发布时间】:2009-05-11 13:40:33 【问题描述】:

我有一个表格,其中使用“ORDER”列对结果进行排序,例如:

Doc_Id    Doc_Value   Doc_Order
1         aaa         1
12        xxx         5
2         bbb         12
3         ccc         24

我的问题是最初设置此订单列时尽可能高效且可重用。

我最初的想法是设置一个标量函数,当向表中添加新条目时可以将其用作默认值:

ALTER FUNCTION [dbo].[Documents_Initial_Order] 
( )
RETURNS int
AS
BEGIN

RETURN (SELECT ISNULL(MAX(DOC_ORDER),0) + 1 FROM dbo.Documents)

当用户想要置换 2 个文档时,我可以轻松地切换 2 个顺序。

它工作得很好,但我现在有第二张桌子我需要以相同的方式设置,我很确定有更好的方法来做到这一点。有什么想法吗?

【问题讨论】:

【参考方案1】:

根据您的评论,我认为您有一个非常可行的解决方案。您可以通过将其指定为默认值来使其更加用户友好:

alter table documents
  add constraint constraint_name 
  default (dbo.documents_initial_order()) for doc_order

作为替代方案,您可以创建一个更新触发器,在插入后将标识字段复制到 doc_order 字段:

create trigger Doc_Trigger
on Documents
for insert
as
update d
set d.doc_order = d.doc_id 
from Documents d
inner join inserted i on i.doc_id = d.doc_id

将 doc_id 定义为标识列的示例:

create table Documents (
    doc_id int identity primary key,
    doc_order int,
    doc_value ntext
)

【讨论】:

好点,但我需要用户能够调整顺序(排列 2 个文档)。如果我使用身份,这样做会很痛苦。 这里的 doc_order 不是 IDENTITY 列 Andomar 的解决方案是一个很好的解决方案。插入触发器会将 doc_order 初始化为 doc_id 值(doc_id 是标识列)。稍后,可以根据需要更新 doc_order。【参考方案2】:

听起来你想要一个标识列,一旦它获得初始值,你就可以覆盖它。一种解决方案是有两列,一次调用“InitialOrder”,这是一个自动增量标识列,然后是第二列称为 doc_order,最初设置为与 InitialOrder 字段相同的值(甚至可能作为如果您以这种方式进行插入,则插入触发器或存储过程),但让用户能够编辑该列。

它确实需要每条记录额外的几个字节,但可以解决您的问题,如果它有任何价值,您将同时获得初始文档顺序和用户重置顺序。

另外,我不确定您的 doc_order 是否需要唯一,但如果不需要,您可以按 doc_order 和 InitialOrder 对返回值进行排序,以确保返回顺序一致。

【讨论】:

(我最后用的方案差不多就是那个)【参考方案3】:

如果不需要对 DOC_ORDER 值进行任何控制,请尝试使用标识列。

【讨论】:

好点,但我需要用户能够调整顺序(排列 2 个文档)。如果我使用身份,这样做会很痛苦。

以上是关于SQL Server 中的自定义排序的主要内容,如果未能解决你的问题,请参考以下文章

sql server自定义排序

SQL Server中使用自定义指定顺序排序

java实现多表的自定义查询。

NSFetchedResultsController 中的自定义排序

Java 为排序构建一个特定的自定义比较器

QTableWidget 中的自定义排序