[SQL] 유사한 문자열을 포함하는 SQL 기록을 찾기
SQL유사한 문자열을 포함하는 SQL 기록을 찾기
500.000 기록을 통해 들어있는 ID와 제목 : 나는 다음과 같은 2 열이있는 테이블이 있습니다. 예를 들면 :
ID Title
-- ------------------------
1 Aliens
2 Aliens (1986)
3 Aliens vs Predator
4 Aliens 2
5 The making of "Aliens"
나는 매우 유사한 레코드를 찾을 필요가 있고, 내 말 것을에 의해 그들은 일반적으로이 차이는 제목의 끝에 3-6 문자에 의해 다릅니다. 나는 어떤 레코드를 반환하는 쿼리를 디자인해야합니다 그래서. 1, 2, 4 이미 levenstein 거리에서 보았다하지만 난 그것을 적용하는 방법을 모르겠어요. 또한 때문에 레코드 수의 쿼리는 밤새을해서는 안된다.
어떤 아이디어 나 제안을 주셔서 감사합니다
해결법
-
==============================
1.당신이 정말로 당신이 당신의 질문에 공식화하는 정확한 방법으로 유사성을 정의 할 경우에 당신은 것입니다 - 당신이 말하는대로 - Levensthein 거리 계산을 구현해야합니다. 어느 쪽의 코드에 의해 또는 DataReader가 SQL 서버 기능으로 검색된 각 행 계산.
당신이 정말로 당신이 당신의 질문에 공식화하는 정확한 방법으로 유사성을 정의 할 경우에 당신은 것입니다 - 당신이 말하는대로 - Levensthein 거리 계산을 구현해야합니다. 어느 쪽의 코드에 의해 또는 DataReader가 SQL 서버 기능으로 검색된 각 행 계산.
언급 한 문제는 당신이 두 개의 문자열 사이의 상호 공유 요소가있을 수 있습니다 알고 가정 할 수 있기 때문에, 첫눈에 나타날 수보다 실제로 더 까다 롭습니다.
그래서 Levenshtein 거리뿐만 아니라 당신은 아마도 (체결 효율적인 유사성 위해) 실제로 일치 할 필요가 연속 된 문자의 최소 수를 지정합니다.
요약하면 : 그것은 지나치게 복잡하고 많은 시간이 소요 / 느린 방법처럼 들린다.
흥미롭게도, SQL Server 2008의이 같은 것을 사용할 수있다 차이 기능을 가지고있다.
두 개의 스트링의 음성 값을 평가하고 그 차이를 계산한다. 당신이 그런는 공백이나 숫자와 문자열의 시작 부분에 그림을 그리 듯 너무 많은 강조를 잘 처리하지 않기 때문에 영화 제목으로 여러 단어로 표현 제대로 작동하도록한다면 나는 확실 해요,하지만 여전히 재미있다 알고 있어야 술어.
당신이 실제로 설명하려고하는 것은 검색 기능의 일종 인 경우에, 당신은 SQL 서버의 전체 텍스트 검색 기능을 조사해야한다 2008 그것은 내장을 제공 동의어 사전 지원, 멋진 SQL 술어와 "최고의 경기"에 대한 순위 메커니즘
편집 : 당신은 중복을 제거하기 위해 찾고 있다면 아마 당신은 SSIS 퍼지 조회 및 퍼지 그룹 변환에 볼 수 있었다. 나는이에게 자신을 시도하지 않은, 그러나 그것은 약속 리드처럼 보인다.
EDIT2 : 당신이 SSIS에 파고 여전히 Levensthein 거리 알고리즘의 성능과 투쟁하지 않으려면, 당신은 아마도 덜 복잡한 것 같습니다이 알고리즘을 시도 할 수 있습니다.
-
==============================
2.대답으로 이미 표시되어 비록 모든 Google 직원에서이 질문에 그 실행은, 나는이에 도움이되는 몇 가지 코드를 공유하는 것이 생각. 당신의 SQL Server에서 CLR 사용자 정의 기능을 할 수있는 좋은 방법입니다 수 당신이 경우에, 당신은 당신에게 dbo.GetSimilarityScore라는 '유사성 점수'() 제공하는 기능이 생성에서 다음 자신의 Levensthein 거리 알고리즘을 구현할 수 있습니다. 나는 뒤죽박죽 단어 순서 및 영숫자가 아닌 문자에 많은 무게를하지 않고, 내 점수 케이스 - 무감각을 기반으로했습니다. 필요에 따라 당신은 당신의 점수 알고리즘을 조정할 수 있지만, 이것은 좋은 시작이다. 저를 얻기 위해이 코드 프로젝트에 링크 된 신용 시작했다.
대답으로 이미 표시되어 비록 모든 Google 직원에서이 질문에 그 실행은, 나는이에 도움이되는 몇 가지 코드를 공유하는 것이 생각. 당신의 SQL Server에서 CLR 사용자 정의 기능을 할 수있는 좋은 방법입니다 수 당신이 경우에, 당신은 당신에게 dbo.GetSimilarityScore라는 '유사성 점수'() 제공하는 기능이 생성에서 다음 자신의 Levensthein 거리 알고리즘을 구현할 수 있습니다. 나는 뒤죽박죽 단어 순서 및 영숫자가 아닌 문자에 많은 무게를하지 않고, 내 점수 케이스 - 무감각을 기반으로했습니다. 필요에 따라 당신은 당신의 점수 알고리즘을 조정할 수 있지만, 이것은 좋은 시작이다. 저를 얻기 위해이 코드 프로젝트에 링크 된 신용 시작했다.
Option Explicit On Option Strict On Option Compare Binary Option Infer On Imports System Imports System.Collections.Generic Imports System.Data Imports System.Data.SqlClient Imports System.Data.SqlTypes Imports System.Text Imports System.Text.RegularExpressions Imports Microsoft.SqlServer.Server Partial Public Class UserDefinedFunctions Private Const Xms As RegexOptions = RegexOptions.IgnorePatternWhitespace Or RegexOptions.Multiline Or RegexOptions.Singleline Private Const Xmsi As RegexOptions = Xms Or RegexOptions.IgnoreCase ''' <summary> ''' Compute the distance between two strings. ''' </summary> ''' <param name="s1">The first of the two strings.</param> ''' <param name="s2">The second of the two strings.</param> ''' <returns>The Levenshtein cost.</returns> <Microsoft.SqlServer.Server.SqlFunction()> _ Public Shared Function ComputeLevenstheinDistance(ByVal string1 As SqlString, ByVal string2 As SqlString) As SqlInt32 If string1.IsNull OrElse string2.IsNull Then Return SqlInt32.Null Dim s1 As String = string1.Value Dim s2 As String = string2.Value Dim n As Integer = s1.Length Dim m As Integer = s2.Length Dim d As Integer(,) = New Integer(n, m) {} ' Step 1 If n = 0 Then Return m If m = 0 Then Return n ' Step 2 For i As Integer = 0 To n d(i, 0) = i Next For j As Integer = 0 To m d(0, j) = j Next ' Step 3 For i As Integer = 1 To n 'Step 4 For j As Integer = 1 To m ' Step 5 Dim cost As Integer = If((s2(j - 1) = s1(i - 1)), 0, 1) ' Step 6 d(i, j) = Math.Min(Math.Min(d(i - 1, j) + 1, d(i, j - 1) + 1), d(i - 1, j - 1) + cost) Next Next ' Step 7 Return d(n, m) End Function ''' <summary> ''' Returns a score between 0.0-1.0 indicating how closely two strings match. 1.0 is a 100% ''' T-SQL equality match, and the score goes down from there towards 0.0 for less similar strings. ''' </summary> <Microsoft.SqlServer.Server.SqlFunction()> _ Public Shared Function GetSimilarityScore(string1 As SqlString, string2 As SqlString) As SqlDouble If string1.IsNull OrElse string2.IsNull Then Return SqlInt32.Null Dim s1 As String = string1.Value.ToUpper().TrimEnd(" "c) Dim s2 As String = string2.Value.ToUpper().TrimEnd(" "c) If s1 = s2 Then Return 1.0F ' At this point, T-SQL would consider them the same, so I will too Dim score1 As SqlDouble = InternalGetSimilarityScore(s1, s2) If score1.IsNull Then Return SqlDouble.Null Dim mod1 As String = GetSimilarityString(s1) Dim mod2 As String = GetSimilarityString(s2) Dim score2 As SqlDouble = InternalGetSimilarityScore(mod1, mod2) If score2.IsNull Then Return SqlDouble.Null If score1 = 1.0F AndAlso score2 = 1.0F Then Return 1.0F If score1 = 0.0F AndAlso score2 = 0.0F Then Return 0.0F ' Return weighted result Return (score1 * 0.2F) + (score2 * 0.8F) End Function Private Shared Function InternalGetSimilarityScore(s1 As String, s2 As String) As SqlDouble Dim dist As SqlInt32 = ComputeLevenstheinDistance(s1, s2) Dim maxLen As Integer = If(s1.Length > s2.Length, s1.Length, s2.Length) If maxLen = 0 Then Return 1.0F Return 1.0F - Convert.ToDouble(dist.Value) / Convert.ToDouble(maxLen) End Function ''' <summary> ''' Removes all non-alpha numeric characters and then sorts ''' the words in alphabetical order. ''' </summary> Private Shared Function GetSimilarityString(s1 As String) As String Dim normString = Regex.Replace(If(s1, ""), "\W|_", " ", Xms) normString = Regex.Replace(normString, "\s+", " ", Xms).Trim() Dim words As New List(Of String)(normString.Split(" "c)) words.Sort() Return String.Join(" ", words.ToArray()) End Function End Class
-
==============================
3.
select id, title from my_table where title like 'Aliens%' and len(rtrim(title)) < len('Aliens') + 7
-
==============================
4.내가 부탁 한 일에서 원래의 제목의 끝에 하나의 단어 이하이어야한다 찾고있는 차이를 상상한다. 이유는 1, 2, 4가 반환되는가요?
내가 부탁 한 일에서 원래의 제목의 끝에 하나의 단어 이하이어야한다 찾고있는 차이를 상상한다. 이유는 1, 2, 4가 반환되는가요?
어쨌든 나는 공백없이 말 검사의 차이가 하나의 단어로 구성하는 질의를했습니다.
declare @title varchar(20) set @title = 'Aliens' select id, title from movies with (nolock) where ltrim(title) like @title + '%' and Charindex(' ', ltrim(right(title, len(title) - len(@title)))) = 0 and len(ltrim(right(title, len(title) - len(@title)))) < 7
그것이 도움이되기를 바랍니다.
-
==============================
5.SQL Server 2008을 사용하는 경우는 전체 텍스트 기능을 사용할 수 있어야합니다.
SQL Server 2008을 사용하는 경우는 전체 텍스트 기능을 사용할 수 있어야합니다.
기본 단계는 다음과 같습니다
1) 컬럼을 통해 전체 텍스트 인덱스를 만듭니다. 이것은 각각의 문자열 (깃발, 스플리터 등) 토큰 화하고 'LIKE THIS'문자열을 검색 할 수 있습니다.
부인은 내가 그것을 사용했던 적이하지만 난 당신이 원하는 것을 할 수 있다고 생각한다는 것입니다.
여기에 읽기 시작 : http://msdn.microsoft.com/en-us/library/ms142571.aspx
from https://stackoverflow.com/questions/5299996/find-sql-records-containing-similar-strings by cc-by-sa and MIT license
'SQL' 카테고리의 다른 글
[SQL] 행 사이 SQL 차이 (0) | 2020.06.27 |
---|---|
[SQL] 위해 SQL 트리 계층 구조 (0) | 2020.06.26 |
[SQL] PostgreSQL을 다른 테이블의 컬럼이있는 테이블의 열을 업데이트 (0) | 2020.06.26 |
[SQL] 에서 테이블을 선택 *에 SQLite는 삽입 (0) | 2020.06.26 |
[SQL] 어떻게 SQL Server 2008을 자체에서 클라이언트 IP 주소를 얻으려면? (0) | 2020.06.26 |