2013-05-23 5 views
-5

null을 허용하는 열의 문자 데이터를 비교하는 데 MIN 함수를 사용했지만 결과가 비참했습니다.모든 것을 varbinary로 변환하면 문자 데이터를 비교하는 올바른 방법이 있습니까?

  1. sys.indexes의 행 수를 결정 :

    select count(*) from sys.indexes; 
    
  2. 실행이 SQL :

    select count(name), substring(cast(min(name) as varbinary),1,1) 
        from sys.indexes; 
    
    을 ;-) 여기 물건의 같은 종류를 보여줍니다 훨씬 단순화 된 예입니다

    카운트가 # 1과 일치하면 여기서 멈추십시오. 대신 다른 데이터베이스를 사용해보십시오.

  3. 메시지 탭으로 이동하십시오. 다음과 같이 표시됩니다. 경고 : 누적 값은 집계 또는 다른 SET 작업에 의해 제거됩니다.

  4. 경고를 해결하기 위해 "이름"열에 null을 어떻게 처리 하시겠습니까? 병합 된 ?

    select count(coalesce(name,char(0x7e))), 
        substring(cast(min(coalesce(name,char(0x7e))) as varbinary),1,1) 
        from sys.indexes; 
    
  5. 주 # 5의 MIN 함수의 결과 (0x7E가보다는 0x63) :

  6. "COALESCE (이름, 문자 (0x7E가))"와 "이름"을 교체하고 SQL을 실행 .

질문 :

A.이 # 4 당 경고를 처리 할 수있는 적절한 방법 누락 (널) 데이터를 병합인가?

B. # 6의 결과가 예상과 다르므로 SQL Server에서 문자 데이터를 비교하는 올바른 방법은 무엇입니까? 모든 것을 varbinary로 변환 하시겠습니까? [편집 ...]

아래 논의

는 유착 통해 널 여분 상기 비교의 결과 사이의 관계에 대한 논의와 혼란이 있었다. 둘 사이의 관계는 다음과 같습니다. 하나의 문자를 포함한 문자열을 null 대체 자리 표시 자로 선택하면 (위의 4 번 및 5 번 단계) 해당 문자열이 현재 비교중인 예상 결과를 만족해야합니다. 쿼리의 다른 데이터 값에 대해 수행됩니다. 일부 데이터 정렬의 경우 적합한 문자열을 찾는 것이 다른 데이터 정렬보다 어려울 수 있습니다. 에

+2

경고를 무시하십시오. 그것은 정보 메시지로서 만 존재합니다. 문자 데이터를 비교하기 위해'varbinary'로 형변환하면 안됩니다. –

+0

경고를 무시하면 카운트가 꺼집니다. 이것이 원래 코드에서 처음부터주의를 끄는 부분입니다.이 코드는 좀 더 복잡합니다. –

+5

'COUNT (col)'는'NOT NULL' 값만을 계산합니다. 행 수를 계산하려면'COUNT (*) '를 사용하십시오. 캐릭터 데이터를 비교하는 것과 어떤면에서 관련이 있는지 알지 못합니다. 원래 가지고 있던 문제를 알려주십시오. –

답변

2

편집 삭제되지

대답 원치 : 예, 또는 당신이이 경우에 유착과 같은 결과()와 ISNULL()를 사용할 수 있습니다.

응답 : 대답 : varchar를 varbinary로 변환하지 마십시오. 비교하지 마십시오. 은 집계를 사용할 때 데이터 정렬 순서를 이해합니다.

내가이 코드는 NULL 문제와 수를 응답 생각하지만, 난 아직도 질문에 대해 조금 혼란 스러워요 :

select count(*) from sys.indexes; 
-- 697 results 
go 
select count(isnull(name,'')) from sys.indexes; 
-- 697 results 
go 
select count(name) from sys.indexes; 
-- 567 results 
go 

그리고 이것은 MIN name 필드 레코드의 수를 얻는다 (기반 정렬 및 문자열 필드의 SQL 정렬 순서)에 :

select i.name 
     ,subCnt.Cnt 
from (select min(name) as name from sys.indexes) as i 
join (select name, count(*) as Cnt from sys.indexes group by name) as subCnt 
on  subCnt.name = i.name; 

그리고이 쿼리 집계 정렬 순서를 설명하고 위의 쿼리는 name 필드에 리턴 값을 선택하는 이유 :

select name, row_number() over (order by name) from sys.indexes order by name; 

그리고 문자 (0x7E가)와 널 (null)을 교체 할 때이 쿼리는 심지어 내 정렬의 (Latin1_General_BIN) 정렬 순서를 보여줍니다

select coalesce(name,char(0x7e)) 
     , row_number() over (order by coalesce(name,char(0x7e))) 
from sys.indexes order by 2; 

을 그리고 이것은 무엇을 결정하는 SQL Server의 데이터 정렬의 정렬 순서의 차이를 (보여줍니다 whateve를 들어, 경고가 표시 널 (null)을 고려 (하지 않고 이름의)

declare @test table (oneChar char(1) collate Latin1_General_BIN 
        , oneChar2 char(1) collate SQL_Latin1_General_CP1_CI_AS 
        , varb varbinary) 

insert into @test (oneChar) 
select 'c' union all 
select '~' union all 
select 'P' union all 
select 'X' union all 
select 'q' union all 
select NULL 

update @test set varb = cast(isnull(oneChar,char(0x7E)) as varbinary), oneChar2 = oneChar 

select min(oneChar) from @test -- 'P' 
select min(oneChar2) from @test -- '~' 
select min(varb) from @test -- 0x50, the varbinary equivalent of oneChar 

그리고 당신은 모든 행의 수를 원하는 경우합니다 (MIN을 원하는 : MIN 또는 MAX)는 문자열 필드에 r reason)을 사용하려면 다음을 사용하십시오.

그리고 무엇을 하든지 필터링을 수행하기 위해 전체 필드를 다른 정렬로 캐스팅하지 마십시오. 이 질문은 간단한 질문/답변이 아닌 토론 포럼에 속합니다. 난 당신이 ISNULL이의 라인을 따라 뭔가 일을 사용할 수없는 이유가 있으리라 믿고있어

+1

응답'A'는 의미를 바꿀 것입니다. '(SELECT 'Foo'UNION ALL SELECT NULL) T (name)'은 (는) 데이터에 존재하지 않더라도 '' '를 반환합니다. –

+0

네, 네 말이 맞아. 나는 OP가 무엇을하려고 하는지를 정말로 이해하지 못한다고 생각한다. –

+0

원래 게시물의 "B"는 # 6의 SQL (여러 가지 비교 연산자를 사용하여 다른 SQL뿐만 아니라)에서 예상 된 결과를 반환하도록 MIN을 시도했지만 시도하지 않았습니다. 두 번째 및 세 번째 SQL 문에 (서브 문자열 및/또는 varbinary가 있거나 없거나 다른 비교 함수/연산자를 사용하여) 대답의 MIN 함수를 추가하십시오. 카운트가 맞으면 비교가 잘못되고 반대의 경우도 마찬가지입니다. –

0

: ISNULL

추신 (MyField는 '내가 아는 것 일부 문자열은 널 (null)입니다') 현재 수행중인 작업 환경에 따라 대규모 데이터 세트에서 성능을 조심하십시오.

+1

이것은 쿼리의 의미를 변경하기 때문에 이미 삭제 된 답변과 같습니다. NULL 인 두 값은'some string'으로 변환되어서는 안됩니다. 왜냐하면 두 개의'NULL' 값 *이 같아야한다고 가정 할 방법이 없기 때문입니다. 이는 'NULL'과 'some string'이 같은 것을 의미하는 경우에만 작동합니다. 정확히 일치하지는 않습니다. –

+0

COLESCE 대신 ISNULL을 사용하면 동일한 결과가 생성됩니다. varbinary와 같이 substring (cast (min, isnull (name, char (0x7e))), 1,1) from sys.indexes; –