按包含十进制值的 Nvarchar 列排序
Order by Nvarchar column containing decimal value
我有以下 table 和 sql 服务器数据库中的数据。我正在尝试按 [Version]
列获取数据顺序。我要结果排列如下:
我怎样才能做到这一点?
CREATE TABLE [dbo].[DocumentLog](
[DocID] [nvarchar](50) NOT NULL,
[Version] [nvarchar](50) NOT NULL) ON [PRIMARY]
GO
INSERT INTO DocumentLog (DocID,[version])values('doc0001','0.1');
INSERT INTO DocumentLog (DocID,[version])values('doc0001','0.5');
INSERT INTO DocumentLog (DocID,[version])values('doc0001','0.3');
INSERT INTO DocumentLog (DocID,[version])values('doc0001','0.4');
INSERT INTO DocumentLog (DocID,[version])values('doc0001','0.2');
INSERT INTO DocumentLog (DocID,[version])values('doc0001','0.6');
INSERT INTO DocumentLog (DocID,[version])values('doc0001','0.7');
INSERT INTO DocumentLog (DocID,[version])values('doc0001','0.9');
INSERT INTO DocumentLog (DocID,[version])values('doc0001','0.8');
INSERT INTO DocumentLog (DocID,[version])values('doc0001','0.10');
INSERT INTO DocumentLog (DocID,[version])values('doc0001','0.11');
INSERT INTO DocumentLog (DocID,[version])values('doc0001','0.12');
INSERT INTO DocumentLog (DocID,[version])values('doc0001','0.13');
INSERT INTO DocumentLog (DocID,[version])values('doc0001','0.14');
INSERT INTO DocumentLog (DocID,[version])values('doc0001','0.15');
INSERT INTO DocumentLog (DocID,[version])values('doc0001','0.16');
INSERT INTO DocumentLog (DocID,[version])values('doc0001','0.17');
INSERT INTO DocumentLog (DocID,[version])values('doc0001','0.18');
INSERT INTO DocumentLog (DocID,[version])values('doc0001','1.0');
INSERT INTO DocumentLog (DocID,[version])values('doc0001','1.1');
INSERT INTO DocumentLog (DocID,[version])values('doc0001','1.10');
INSERT INTO DocumentLog (DocID,[version])values('doc0001','2.0');
我想你正在寻找这样的东西:
SELECT
*,
TRY_CAST(LEFT([version], CHARINDEX('.', [version])-1) AS int) MainVer,
TRY_CAST(RIGHT([version], LEN([version]) - CHARINDEX('.', [version])) AS int) AS SubVer
FROM DocumentLog
ORDER BY MainVer, SubVer;
对于 2012 年之前的 SQL 服务器,将 TRY_CAST
替换为 CAST
。
真正的问题是您的 table 结构。您应该有两列(或软件版本控制模型中的四列)来保存版本信息。因为你没有,所以你必须以一种完全复杂的方式来处理这个问题。由于您的数据似乎是一致的,您可以为此利用 PARSENAME。
select *
from DocumentLog
order by convert(int, PARSENAME(Version, 2))
, convert(int, PARSENAME(Version, 1))
我有以下 table 和 sql 服务器数据库中的数据。我正在尝试按 [Version]
列获取数据顺序。我要结果排列如下:
我怎样才能做到这一点?
CREATE TABLE [dbo].[DocumentLog](
[DocID] [nvarchar](50) NOT NULL,
[Version] [nvarchar](50) NOT NULL) ON [PRIMARY]
GO
INSERT INTO DocumentLog (DocID,[version])values('doc0001','0.1');
INSERT INTO DocumentLog (DocID,[version])values('doc0001','0.5');
INSERT INTO DocumentLog (DocID,[version])values('doc0001','0.3');
INSERT INTO DocumentLog (DocID,[version])values('doc0001','0.4');
INSERT INTO DocumentLog (DocID,[version])values('doc0001','0.2');
INSERT INTO DocumentLog (DocID,[version])values('doc0001','0.6');
INSERT INTO DocumentLog (DocID,[version])values('doc0001','0.7');
INSERT INTO DocumentLog (DocID,[version])values('doc0001','0.9');
INSERT INTO DocumentLog (DocID,[version])values('doc0001','0.8');
INSERT INTO DocumentLog (DocID,[version])values('doc0001','0.10');
INSERT INTO DocumentLog (DocID,[version])values('doc0001','0.11');
INSERT INTO DocumentLog (DocID,[version])values('doc0001','0.12');
INSERT INTO DocumentLog (DocID,[version])values('doc0001','0.13');
INSERT INTO DocumentLog (DocID,[version])values('doc0001','0.14');
INSERT INTO DocumentLog (DocID,[version])values('doc0001','0.15');
INSERT INTO DocumentLog (DocID,[version])values('doc0001','0.16');
INSERT INTO DocumentLog (DocID,[version])values('doc0001','0.17');
INSERT INTO DocumentLog (DocID,[version])values('doc0001','0.18');
INSERT INTO DocumentLog (DocID,[version])values('doc0001','1.0');
INSERT INTO DocumentLog (DocID,[version])values('doc0001','1.1');
INSERT INTO DocumentLog (DocID,[version])values('doc0001','1.10');
INSERT INTO DocumentLog (DocID,[version])values('doc0001','2.0');
我想你正在寻找这样的东西:
SELECT
*,
TRY_CAST(LEFT([version], CHARINDEX('.', [version])-1) AS int) MainVer,
TRY_CAST(RIGHT([version], LEN([version]) - CHARINDEX('.', [version])) AS int) AS SubVer
FROM DocumentLog
ORDER BY MainVer, SubVer;
对于 2012 年之前的 SQL 服务器,将 TRY_CAST
替换为 CAST
。
真正的问题是您的 table 结构。您应该有两列(或软件版本控制模型中的四列)来保存版本信息。因为你没有,所以你必须以一种完全复杂的方式来处理这个问题。由于您的数据似乎是一致的,您可以为此利用 PARSENAME。
select *
from DocumentLog
order by convert(int, PARSENAME(Version, 2))
, convert(int, PARSENAME(Version, 1))