Sql server 按字符串的一部分排序

Sql server 按字符串的一部分排序,sql-server,tsql,sorting,sql-server-2008-r2,Sql Server,Tsql,Sorting,Sql Server 2008 R2,基本上,我有一个表格“歌曲”,就像这个例子 我需要获取数据并显示在gridview中。桌子很乱,歌曲可以按任何顺序排列,不一定按专辑或歌手分组。我需要先按singer对行进行排序,它应该按字母顺序对艺术家进行排序。相册也应该分组。但更重要的是,歌曲应该按字母顺序或数字排序 上表显示了我想要的理想排序列表。有人能指出如何为此编写T-SQL吗。我使用的是SQL Server 2008 R2。按歌手、专辑、标题排序的唯一问题是标题包含数字和字符串(这不太好,因为它打破了1NF)。如果您对标题格式有绝

基本上,我有一个表格“歌曲”,就像这个例子

我需要获取数据并显示在gridview中。桌子很乱,歌曲可以按任何顺序排列,不一定按专辑或歌手分组。我需要先按singer对行进行排序,它应该按字母顺序对艺术家进行排序。相册也应该分组。但更重要的是,歌曲应该按字母顺序或数字排序


上表显示了我想要的理想排序列表。有人能指出如何为此编写T-SQL吗。我使用的是SQL Server 2008 R2。

按歌手、专辑、标题排序的唯一问题是标题包含数字和字符串(这不太好,因为它打破了1NF)。如果您对
标题
格式有绝对的把握,您可以这样做

select  *
from    Songs
order by
        Singer
,       Album
,       Title
ORDER BY Singer, Album,
cast(substring(Title,0,CHARINDEX( '.',Title)) as int),
substring(Title,CHARINDEX( '.',Title)+1,LEN(Title))
-- LEN(Title) should work, even though it would be more correct to put the right number of
-- characters (from position of '.' to the end)

你需要选择是按字母顺序(不太可能是IMHO)还是按数字顺序(更可能是,因为我不想按原意以外的任何顺序听《月球的黑暗面》)。正如我在上面的评论中提到的,你不能两者兼而有之

按编号排序:

SELECT Title, Singer, Album
  FROM dbo.Songs
  ORDER BY Singer, Album, 
    CONVERT(INT, SUBSTRING(Title, 1, CHARINDEX('.', Title)));
要按字母顺序排列标题,请执行以下操作:

SELECT Title, Singer, Album
  FROM dbo.Songs
  ORDER BY Singer, Album, 
    SUBSTRING(Title, CHARINDEX('.', Title) + 1, 255); 
    -- 255 or whatever the column is defined as
很多人会建议
LEN(Title)
,但对我来说,这是一个不必要的计算。IMHO是唯一合理的情况,它是在模式发展迅速且该列的最大长度不能被视为“稳定”的情况下。在这些情况下,我仍然建议使用更高的数字,以适应该列未来的任何大小增加,例如
4000

> A1EX07暗示,您应该考虑单独存储号码和标题。您可以按如下方式执行此操作:

ALTER TABLE dbo.Songs ADD SongNumber TINYINT;
ALTER TABLE dbo.Songs ADD SongTitle VARCHAR(255);

UPDATE dbo.Songs SET 
  SongNumber = CONVERT(TINYINT, SUBSTRING(Title, 1, CHARINDEX('.', Title))),
  SongTitle  = SUBSTRING(Title, CHARINDEX('.', Title) + 1, 255);

-- once you've verified:    
ALTER TABLE dbo.Songs DROP COLUMN Title;

您还必须更新访问此表的任何进程(或创建一个视图并将它们指向视图)。现在,如果您想按
SongNumber
SongTitle
排序,那么您的
orderby
子句要简单得多。(但你仍然无法同时按这两种方式进行排序,如果你仔细想想,这是很有意义的。)

你希望歌曲按字母顺序还是按数字排序?你不能同时做这两件事。歌曲只需要按数字排序。谢谢:)我不认为将剩余的标题转换为
INT
是可行的(也许你的意思是
VARCHAR(某物)
?)。我还认为你最后一个括号的位置不正确。@Aaron Bertrand:是的,复印时打印错误。修正题a1ex07,顺便说一句,它突破1NF是什么意思?我承认我不是一个真正的前端设计师,也不是一个真正的db人。你能为我推荐一个更好的数据库接口吗?谢谢..@Laurence Nyein:您正在一列中存储两个实体:编号(例如01)和标题(例如“某时”)。1NF要求所有列都是正则的(只保留一个属性)。我有一个列(整数类型)和ValHAR/VARCHAR2用于标题iSelf.你认为我是否还有一个列(可能是排序)存储排序号(1, 2, 3)?这将进行数值排序,但不考虑OP的其他选项(按字母顺序排序标题-可能不包括开头的
01.
etc).+1答案不错,除了微优化字符串操作。甚至提到2012年
len
的成本都很奇怪。@Andomar我不明白,为什么要在不需要的时候执行计算,即使增量成本很小?让我澄清一下,我并不是建议使用len()的代码在中,需要重新编写,如“我看到您的查询中有LEN(),让我们通过删除它将查询的性能提高一倍。”这是微观优化,没有必要。我反对LEN()作为一个答案,被一个受尊敬的社区成员,当它不是必要的,浪费的,并不是原来的问题的一部分。虽然是,“废物”是可以忽略不计的,它背后的想法,我认为更有毒-整个“好,它不是那么昂贵……”有点像“磁盘空间便宜”。论点。谢谢Aaron,回答得很好,但我想没有更简单的解决方案了。除了打破town表,如Songs表、Artists表和Albums表……如果你按数字排序,我认为解决方案没有那么复杂。如果你把数字放在它自己的列中,你可能会使它变得更简单,但这并不重要ally将查询更改这么多。也就是说,如果您存储了很多专辑,那么将艺人和专辑划分到各自的表中可能会有相当大的意义,这样您就不会对该专辑中的每首歌曲重复
Pink Floyd
'Dark Side of the Moon'
。现在,您的模式已完全非规范化,并且在某些情况下,这是可以的,甚至更好。