2011-08-10 84 views
2

我正在使用SQL Server 2008.排序在TSQL

我想通过使用DetailRefNumber排序我的结果。然而,我无法实现像

2.1 
2.2 
2.3 
xxx 
xxx 
2.10 
2.11 
2.12 

请你指导我如何做到这一点?

enter image description here谢谢。

+0

'DetailRefNumber'是什么类型? –

+1

它的类型是什么?请不要说char/varchar/nvarchar – JonH

+0

不幸的是,它是varchar(20) – TTCG

回答

2

您可以尝试PARSENAME

ORDER BY CAST(PARSENAME(DetailRefNumber,2) AS INT),CAST(PARSENAME(DetailRefNumber,1) AS INT) 
+0

+1一个整洁的把戏! – Blorgbeard

+0

谢谢大家的帮助。你们给了我很多其他的想法和知识。我非常感谢你的帮助和贡献。感谢数百万。 – TTCG

3

我已经 从来没有 只是试过这个,但你可以尝试CASTCONVERT列的顺序?

尝试......

SELECT 
... 
FROM 
... 
ORDER BY 
CAST(MyColumn AS Decimal(18,2)) 

这工作:

CREATE TABLE #t 
(
    mycol varchar(20) 
) 

INSERT INTO #t(mycol) VALUES('1.0') 
INSERT INTO #t(mycol) VALUES('1.10') 
INSERT INTO #t(mycol) VALUES('2.10') 
INSERT INTO #t(mycol) VALUES('21.20') 
INSERT INTO #t(mycol) VALUES('2.00') 

SELECT * FROM #t ORDER BY CAST(mycol as Decimal(18,2)) 

DROP TABLE #t 

enter image description here

你的将成为:

SELECT 
    AssessmentID, 
    AssessmentRefNumber, 
    DetailRefNumber 
FROM 
    Assessments 
ORDER BY 
    CAST(DetailRefNumber As Decimal(18,2)) 

编辑

只注意到“版本号排序”。 就拿正是我所做的和改变的最后一部分,愉快使用子/什么marc_s发布的作品:

CREATE TABLE #t 
(
    mycol varchar(20) 
) 

INSERT INTO #t(mycol) VALUES('1.0') 
INSERT INTO #t(mycol) VALUES('1.2') 
INSERT INTO #t(mycol) VALUES('1.11') 
INSERT INTO #t(mycol) VALUES('2.10') 
INSERT INTO #t(mycol) VALUES('21.20') 
INSERT INTO #t(mycol) VALUES('2.20') 
INSERT INTO #t(mycol) VALUES('2.00') 
INSERT INTO #t(mycol) VALUES('2.11') 
INSERT INTO #t(mycol) VALUES('2.2') 

SELECT 
    * 
FROM #t 
ORDER BY 
    CAST(LEFT(mycol, CHARINDEX('.', myCol)-1) AS int), 
    CAST(SUBSTRING(myCol, CharINDEX('.', mycol)+1, 999) AS int) 
+0

不行 - 尝试在那里放置一个'1.2':应该出现在'1.0'之后但在'1.10'之前 – Blorgbeard

+0

这会导致2.1和2.10被认为是等同的......和2。3将在2.10之后结束。 – GendoIkari

+0

这就是aminor的细节,关键是你可以使用CAST/CONVERT来排序你的元素,只需使用一个子串。 – JonH

1

您需要使用SUBSTRING和CAST ...

order by 
    CAST(SUBSTRING(DetailRefNumber, 0, 1) as int), 
    CAST(SUBSTRING(DetailRefNumber, 2, LEN(DetailRefNumber) - 2) as int) 

首先会为了通过小数点前的数字,然后小数点后的数字,并且2.10大于2.3。

+0

由于'SUBSTRING'不可SARGable,因此这将强制进行表扫描 – JNK

+0

此外,这里假设“整数”是一位数字。当他们遇到'10.1','10.2'等时会发生什么? –

+0

我的意思是它比起完整的复制粘贴解决方案更像一个起点。 – GendoIkari

5

如果DetailRefNumber总是是一个数字,用点分隔的,你可以添加两个计算列于表基本上采取列分割成两个独立的,数值:

alter table dbo.YourTable 
    add RefNrMajor AS CAST(LEFT(DetailRefNumber, CHARINDEX('.', DetailRefNumber) - 1) AS INT) PERSISTED 

alter table dbo.YourTable 
    add RefNrMinor AS CAST(SUBSTRING(DetailRefNumber, CHARINDEX('.', DetailRefNumber) + 1, 999) AS INT) PERSISTED 

和现在你可以通过这些新的数字列命令:

SELECT (columns) 
FROM dbo.YourTable 
ORDER BY RefNrMajor, RefNrMinor 
+0

+1我没有注意到“版本”号码的排序,所以这肯定会做到这一点。 – JonH

0
select * 
from yourTable 
order by 
assessmentRefNum, 
convert(int,right(detailRefNum,len(detailRefNum)-charindex('.',detailRefNum,1))); 
+0

你试过了吗?就像@ Christian的回答一样,这也会错误地将'2.10'在'2.3'之前排序,无论'assessmentRefNum'是字符串还是数字。 –

+0

是的,我使用assessmentRefNum varchar(1)和detailRefNum varchar(5)运行它,值正确排序。我会发布图片,但由于我是新的,我不能。 – Chris