2012-07-18 4 views
2

저는 숫자를 수동으로 입력 할 수있는 열을 가질 수있는 방법을 찾고 있습니다. 그러면 목록이이 목록을 기반으로 정렬 될 것입니다. 이것은 C# 목록에 대한 언어 및 그것의 ms로 SQL분수와 혼합 숫자 목록을 주문하십시오.

나는 많은 정보가 없지만 누구든지 알고 싶다면 자유롭게 물어보고 최선의 능력을 시험해 보겠습니다.

이들은 현재 문자열로 저장되어 있습니다.

목록의 일부가 범위를 포함하지만 일부는 분수를 포함하고 있기 때문에 같은 IE 1/2는 1-2 또는 1/2 (반쪽)을 나타낼 수 있습니다.

모든 SQL 연결은 NHibernate를 사용하여 수행됩니다.

간단히 정렬하지 않는 이유는 현재 분수를 사용하여 목록이 정렬되고 목록이 제대로 작동하지만 1을 초과하면 모든 항목이 깨져서 목록 맨 아래에 모두 표시된다는 것입니다. IE는 :이 일을하고 싶은 방법

Image List

예 :

나는 그 라인을 따라 "DisplayOrder"또는 뭔가 이름을 내 데이터베이스의 열을 가질 것이다.

데이터베이스 행에 "1"이 표시되면 목록의 첫 번째 항목이됩니다. 데이터베이스 행에 "8"이라고 표시되면 목록에있는 8 번째 항목이 표시됩니다.

+5

샘플 데이터와 원하는 결과를 제공하십시오. – RedFilter

+0

목록을 정렬하는 중입니까? 왜 당신이 데이터베이스로 그것을 할 수있는 이유가 있습니까? 이 목록에 중복이 있습니까? –

+0

난 당신이 당신이 DB를 쿼리 순서에 의해 DisplayOrder에 의해 수행하는 것이 좋습니다 – HatSoft

답변

0

전화 수레로 변환 비교 및 분류에 사용됩니다. "위생"단계에서 더 많은 것을 필요로 할 수 있으며 공백을 정상화하고 다른 문자를 제거하는 등의 일을 할 수 있습니다. 제수를 0으로 확인해야 할 수도 있습니다 (데이터 만 알면됩니다).

create function dbo.FractionToFloat(@fraction varchar(100)) 
returns float 
as 
begin 
    declare @input varchar(100) 
     , @output float 
     , @whole int 
     , @dividend int 
     , @divisor int 

    -- Sanitize input 
    select @input = ltrim(rtrim(replace(replace(@fraction, '''', ''), '"', ''))) 

    select @whole = cast(case 
     when charindex('/', @input) = 0 then @input 
     when charindex(' ', @input) = 0 then '0' 
     else left(@input, charindex(' ', @input) - 1) 
     end as int) 

    select @dividend = cast(case 
     when charindex('/', @input) = 0 then '0' 
     when charindex(' ', @input) = 0 then left(@input, charindex('/', @input) - 1) 
     else substring(@input, charindex(' ', @input) + 1, charindex('/', @input) - charindex(' ', @input) - 1) 
     end as int) 

    select @divisor = cast(case 
     when charindex('/', @input) = 0 then '1' 
     else right(@input, charindex('/', reverse(@input)) - 1) 
     end as int) 

    select @output = cast(@whole as float) + (cast(@dividend as float)/cast(@divisor as float)) 

    return @output 
end 

이 방법을 수행 할 수 있습니다 그래서 같은 기능의 출력에 의해 단순히 순서 :

select * 
from MyTable 
order by dbo.FractionToFloat(MyFractionColumn) 
내가하지 일반적으로 사용자가 데이터 변경으로 유지해야 자신의 파서를 압연 제안

하지만,이 표면에서 충분히 단순 해 보이며 서수 컬럼을 수동으로 유지하는 것보다 낫다. 또한 다양한 단위 (피트에서 인치, 분에서 초)를 비교해야만한다면이 작업은 더욱 복잡해집니다. 데모 데이터에서 단위처럼 보이는 부분은 제거하고 있습니다.

0

정렬 결과는 완전히 정상적으로 보입니다. 데이터베이스가 "1 1/4"이 무엇을 의미하는지 이해할 수 없다고 생각하기 때문입니다. 데이터베이스 필드에는 어떤 유형이 있습니까? 텍스트/varchar/string 같아요?

어쩌면 당신이 숫자들에 분수 값을 변환하는 저장된 프로 시저를 작성해야합니다,는 어떤 수, 당신의 분수를 분석하기 위해 함께 빠른 기능을 넣었습니다

SELECT field1, field2, ParseAndConvertProc(DisplayOrder) as disp_order ORDER by disp_order 
+0

제품의 범위에 들어가기 전까지는 기본 정렬 방법을 사용하여 제품이 나옵니다 즉 1/2 (반)이지만 또한 1/2 (1-2) 범위로 표시되기 때문에이 문제를 해결하는 가장 좋은 방법은 단순히 열이 비어 있는지 확인하는 것입니다. –

+0

이것은 분수와 범위가 다르게 표시되어 작동하지 않습니다. –

+0

예, 이것이 문제의 일부입니다. 모든 것을 이해했는지를 요약 해 보겠습니다. 문제는 무엇입니까? 1) 분수 값이 텍스트로 저장됩니다 (명백한 도움말/proc없이 SQL 서버에 의해 분수 값으로 구문 분석하는 것을 불가능하게 만듭니다) 2) 값에 상수 구문을 사용할 수 없습니다 : 때때로 '/' , 때로는 '-', 때로는 '1/2'대신 '3/2'가됩니다. 내가 잘못한거야? – mbarthelemy

0

1/2between 1 and 2을 의미하는 순간을 무시하고 광기에 시달리고 그 중 일부 주문을 시도 할 수 있습니다.

CREATE TABLE #Fractions (
    Frac varchar(15) 
); 

INSERT #Fractions VALUES 
    ('1 1/2'), ('1 1/4'), ('1"'), ('1/2'), ('1/4'), ('1/8'), 
    ('2 1/2'), ('2"'), ('3"'), ('3/4'), ('3/8'), ('4"'); 

WITH Canonical AS (
    SELECT 
     Frac, 
     F, 
     CharIndex(' ', F) S, 
     CharIndex('/', F) D 
    FROM 
     (SELECT Frac, Replace(Frac, '"', '') F FROM #Fractions) F 
    WHERE 
     F NOT LIKE '%[^0-9 /]%' 
), Parts AS (
    SELECT 
     Frac, 
     Convert(int, Left(F, CASE WHEN D = 0 THEN Len(F) ELSE S END)) W, 
     Convert(int, CASE WHEN D > 0 THEN Substring(F, S + 1, D - S - 1) ELSE '' END) N, 
     Convert(int, CASE WHEN D > 0 THEN Substring(F, D + 1, 2147483647) ELSE '1' END) D 
    FROM Canonical 
) 
SELECT 
    Frac, 
    W + N * 1.0/D Calc 
FROM Parts 
ORDER BY Calc; 

DROP TABLE #Fractions; 

하지만 권장하지 않습니다.올바른 값을 얻으려면 내 쿼리를 기준으로 사용하고 10 진수 값을 사용하려면 전환하십시오.

위의 패턴 일치를 NOT LIKE 대신 LIKE를 사용하여이 코드에서 고려하지 않은 문자에 대한 데이터를 검색해야합니다. 그런 다음 어떻게 든 제거하거나 설명하십시오.

만약 당신이 말한 바가 1/2은 두 가지를 의미 할 수 있으며, 그 차이점을 말할 수 있다면, 그것에 대해 뭔가를 할 수 있습니다. 범위를 두 개의 열에 저장하십시오. 동일하다면 범위가 없습니다.

두 가지 의미의 차이점을 알 수 없다면 당신은 크게 혼란스러워하고 직장을 그만두고 알래스카의 레이스 썰매 개로 갈 수도 있습니다.

관련 문제