0

基本上我有一个像这个例子一样的“歌曲”表。

在此处输入图像描述

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

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

4

3 回答 3

1
select  *
from    Songs
order by
        Singer
,       Album
,       Title
于 2012-04-21T14:38:15.150 回答
1

您需要选择是要按字母顺序(不太可能是恕我直言)还是按数字(更可能,因为我不想以除原始意图之外的任何顺序听《月亮的黑暗面》)来排序专辑中的歌曲)。正如我在上面的评论中提到的那样,你不能两者都做。

按数字排序:

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),但对我来说,这是一个不必要的计算。恕我直言,唯一合理的情况是模式发展迅速并且该列的最大长度不能被视为“稳定”的情况。在这些情况下,我可能仍然建议只使用一个更高的数字,以适应该列的任何未来大小增加,例如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;

您还必须更新访问此表的所有进程(或创建一个视图并将它们指向该视图)。现在,如果您想按SongNumberor排序SongTitle,您的ORDER BY子句要简单得多。(但您仍然无法同时对两者进行排序,如果您考虑一下,这很有意义。)

于 2012-04-21T17:38:56.797 回答
0

看起来排序依据的唯一问题Singer, Album,Title是标题包含数字和字符串(这不好,因为它破坏了 1NF)。如果您绝对确定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)
于 2012-04-21T14:59:15.117 回答