从查询结果中重新订购单个项目

3

我正在寻找一个优雅的解决方案来解决我的订购问题。

我有一个数据库查询,返回按名称排序的结果列表。结果将始终包含一个名为“主项目”的项目,该项目始终需要出现在结果列表的第一位。该项目没有在数据库中标记为单独字段,因此需要通过名称进行识别。

例如,如果结果如下:

"A Item"
"B Item"
"Main Item"
"Y Item"
"Z Item"

我需要保留按字母顺序排列的功能,但是要求“主要项目”首先出现:

"Main Item"
"A Item"
"B Item"
"Y Item"
"Z Item"

返回此数据的查询是用pl/sql编写的,我可以修改查询或在.Net方面执行一些操作,其中我拥有一个IEnumerable对象,该对象包含结果对象的集合。


客户端的集合有多大?它是否足够大或经常被调用,以禁止在客户端进行排序? - Geoff Cox
通常不大,一般小于10。 - zaq
3个回答

3
您可以堆叠您的订单:
query
  .OrderBy(item => item.Title) // alphabetical
  .OrderByDescending(item => item.Title == "Main Item"); // put Main Item first, bool==true

编辑

该列表已经预排序,因此只需要第二个 OrderBy

query.OrderByDescending(item => item.Title == "Main Item");

这是一个漂亮的答案。我只需要第二个orderby,因为集合已经按字母顺序排序了。 - zaq
@zaq 啊,我之前读你的帖子太快了,现在我明白你说它是预订的了。 - payo

0

尝试这个查询:

SELECT * 
FROM MyTable 
ORDER BY 
        CASE 
            WHEN Name = 'Main Item' THEN ' ' 
            ELSE Name 
        END

0

我喜欢Payo的答案,但由于它需要第二次遍历整个集合而不是简单的元素移动逻辑,所以我认为也应该发布这个答案:

List<MyClass> items = GetItemsFromDB();

int i = items.FindIndex(x => x.Name == "Main Item");

MyClass mainItem = items[i];
items.RemoveAt(i);
items.Insert(0, mainItem);

这个代码看起来很像是过早的(微)优化,FindIndex 的时间复杂度也是 O(n)。只有在列表非常长的情况下才会有明显的影响,最坏情况下的性能仍然相同。现在这段代码变得容易出错且难以阅读。 - sehe
@sehe 我认为代码仍然非常明显,而且在最佳情况下确实有改进,这也应该同样考虑到。 - SimpleVar
@sehe,你可以将搜索算法复杂度提高到nLogn等级。这个答案的重点是单元素移动逻辑。 - SimpleVar
我的观点是,即使在最好的情况下也没有实际的改进:列表不会足够大以产生这种差异:通常不大,通常小于10 - sehe
另一个问题是我有一个IEnumerable而不是列表,它不支持RemoveAt或Insert。 - zaq

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接