基本上我有一个像这个例子一样的“歌曲”表。
我需要获取数据并在网格视图中显示。桌子很乱,歌曲可以按任何顺序排列,不一定按专辑或歌手分组。我需要先按歌手对行进行排序,它应该按字母顺序对艺术家进行排序。专辑也应该分组。但更重要的是,歌曲应按字母顺序/或数字排序。
上表显示了我想要的理想排序列表。谁能指出如何为此编写T-SQL。我正在使用 SQL Server 2008 R2。
基本上我有一个像这个例子一样的“歌曲”表。
我需要获取数据并在网格视图中显示。桌子很乱,歌曲可以按任何顺序排列,不一定按专辑或歌手分组。我需要先按歌手对行进行排序,它应该按字母顺序对艺术家进行排序。专辑也应该分组。但更重要的是,歌曲应按字母顺序/或数字排序。
上表显示了我想要的理想排序列表。谁能指出如何为此编写T-SQL。我正在使用 SQL Server 2008 R2。
select *
from Songs
order by
Singer
, Album
, Title
您需要选择是要按字母顺序(不太可能是恕我直言)还是按数字(更可能,因为我不想以除原始意图之外的任何顺序听《月亮的黑暗面》)来排序专辑中的歌曲)。正如我在上面的评论中提到的那样,你不能两者都做。
按数字排序:
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;
您还必须更新访问此表的所有进程(或创建一个视图并将它们指向该视图)。现在,如果您想按SongNumber
or排序SongTitle
,您的ORDER BY
子句要简单得多。(但您仍然无法同时对两者进行排序,如果您考虑一下,这很有意义。)
看起来排序依据的唯一问题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)