我需要帮助来订购下一个声明:
select numbering from QuestionnaireQuestion where
QuestionnaireQuestion.questionnaire_id = 20 AND
QuestionnaireQuestion.numbering is not null
order by LEFT(numbering,PATINDEX('%[0-9]%',numbering)-1)
结果是:
Q2
Q2.a
Q2.b
Q3
Q4
Q4.a
Q5
Q6
Q6.a
Q6.a.1
Q6.a.2
Q6.a.3
Q6.a.4
Q7
Q8
Q8.a
Q9
Q10
Q10.a
Q10.b
Q11
Q11.a
Q12
Q12.a
Q12.b
Q13
Q13.a
Q13.a.1
Q13.a.2
Q13.a.3
Q13.a.4
Q13.a.5
Q13.a.6
Q13.a.7
Q13.a.8
Q13.b
Q13.b.1
Q13.b.2
Q13.b.3
Q13.b.4
Q13.b.5
Q13.b.6
Q13.b.7
Q13.b.8
Q1
最后一个是Q1,但我需要TOP中的Q1
答案 0 :(得分:1)
我相信你需要子串,而不是左边的
order by substring(numbering,PATINDEX('%[0-9]%',numbering),100)
然而,这不会解决10及以上,但以下将:
select numbering , right('0000'+substring(numbering,pos1,pos2-pos1),4)
from QuestionnaireQuestion
cross apply (
select PATINDEX('%[0-9]%',rtrim(numbering)), PATINDEX('%[.]%',rtrim(numbering)+'.')
) ca (pos1, pos2)
order by right('0000'+substring(numbering,pos1,pos2-pos1),4), numbering
它"左脚垫"发现的第一个号码6变为0006或91变为0091等等。
交叉应用用于计算字符串中的2个位置,其中找到第一个数字,以及找到第一个句点的位置(&注意添加一个句点以确保此值始终为正)。从这些位置开始,第一个数字被隔离,然后连接到' 0000'例如。 6变为00006或91变为000091,则只使用右4个字符,因此我们得到0001 .... 9999种可能性。
dbfiddle demo here
答案 1 :(得分:0)
这里真正的挑战是你将多个信息存储在一个元组中。这违反了1NF并且真的很糟糕。由于你有不同数量的元素,这更加困难。假设你永远不会超过3个元素,你可以使用一些丑陋的字符串操作作为黑客来使这项工作。请注意,这种情况的表现不会很好,但这是因为设计不够理想。
declare @Something table (SomeValue varchar(20))
insert @Something (SomeValue) values
('Q2')
, ('Q2.a')
, ('Q2.b')
, ('Q3')
, ('Q4')
, ('Q4.a')
, ('Q5')
, ('Q6')
, ('Q6.a')
, ('Q6.a.1')
, ('Q6.a.2')
, ('Q6.a.3')
, ('Q6.a.4')
, ('Q7')
, ('Q8')
, ('Q8.a')
, ('Q9')
, ('Q10')
, ('Q10.a')
, ('Q10.b')
, ('Q11')
, ('Q11.a')
, ('Q12')
, ('Q12.a')
, ('Q12.b')
, ('Q13')
, ('Q13.a')
, ('Q13.a.1')
, ('Q13.a.2')
, ('Q13.a.3')
, ('Q13.a.4')
, ('Q13.a.5')
, ('Q13.a.6')
, ('Q13.a.7')
, ('Q13.a.8')
, ('Q13.b')
, ('Q13.b.1')
, ('Q13.b.2')
, ('Q13.b.3')
, ('Q13.b.4')
, ('Q13.b.5')
, ('Q13.b.6')
, ('Q13.b.7')
, ('Q13.b.8')
, ('Q1')
, ('Q11')
select *
from @Something s
order by reverse(PARSENAME(reverse(s.SomeValue), 1))
, reverse(PARSENAME(reverse(s.SomeValue), 2))
, reverse(PARSENAME(reverse(s.SomeValue), 3))
--If you have 4 elements you can add one more level.
--But this will not work if you exceed 4 elements because of how PARSENAME works.
--, reverse(PARSENAME(reverse(s.SomeValue), 4))