En résumé, vous avez besoin d'une signature pour chaque paragraphe, puis comparez les signatures. Vous n'avez pas mentionné la nature de la sortie elle-même. . Ici, je "suis de retour d'une rangée de valeurs ParagraphId de délimité par des virgules pour chaque signature de paragraphe identique
With ParagraphSigs As
(
Select P.ParagraphId
, Hashbytes('SHA1'
, (
Select '|' + S1.Text
'|' + Cast(S1.Offset As varchar(10))
'|' + Cast(S1.Score As varchar(10))
From Sentence As S1
Where S1.ParagraphId = P.ParagraphId
Order By S1.SentenceId
For Xml Path('')
)) As Signature
From Paragraph As P
)
Select Stuff(
(
Select ', ' + Cast(PS1.ParagraphId As varchar(10))
From ParagraphSigs As PS1
Where PS1.Signature = PS.Signature
For Xml Path('')
), 1, 2, '') As Paragraph
From ParagraphSigs As PS
Group By PS.Signature
Étant donné que vous plus à propos de la sortie désirée, vous pouvez modifier la requête comme ceci:
With ParagraphSigs As
(
Select P.ParagraphId
, Hashbytes('SHA1'
, (
Select '|' + S1.Text
'|' + Cast(S1.Offset As varchar(10))
'|' + Cast(S1.Score As varchar(10))
From Sentence As S1
Where S1.ParagraphId = P.ParagraphId
Order By S1.SentenceId
For Xml Path('')
)) As Signature
From Paragraph As P
)
Select P1.ParagraphId, P2.ParagraphId As EquivParagraphId
From ParagraphSigs As P1
Left Join ParagraphSigs As P2
On P2.Signature = P1.Signature
And P2.ParagraphId <> P1.ParagraphId
Évidemment, il est possible que trois ou quatre paragraphes partagent la même signature, donc soyez averti que les résultats ci-dessus vous donneront un produit cartésien de paragraphes correspondants (par exemple (P1, P2), (P1, P3), (P2, P1), (P2, P3), (P3, P1), (P3, P2))
Dans les commentaires, vous avez demandé abo Je cherche effectivement sur la dernière phrase. Puisque vous avez deux autres paramètres, vous pouvez réduire le nombre de signatures générées en faisant en comparant les deux colonnes int première:
With ParagraphsNeedingSigs As
(
Select P1.ParagraphId
From Paragraph As P1
Where Exists (
Select 1
From Paragraph As P2
Where P2.ParagraphId <> P1.ParagraphId
And P2.Offset = P1.Offet
And P2.Score = P1.Score
)
)
, ParagraphSigs As
(
Select P.ParagraphId
, Hashbytes('SHA1'
, (
Select '|' + S1.Text
'|' + Cast(S1.Offset As varchar(10))
'|' + Cast(S1.Score As varchar(10))
From Sentence As S1
Where S1.ParagraphId = P.ParagraphId
Order By S1.SentenceId
For Xml Path('')
)) As Signature
From ParagraphsNeedingSigs As P
)
Select P.ParagraphId, P2.ParagraphId As EquivParagraphId
From Paragraph As P
Left Join ParagraphSigs As P1
On P1.ParagraphId = P.ParagraphId
Left Join ParagraphSigs As P2
On P2.Signature = P1.Signature
And P2.ParagraphId <> P1.ParagraphId
Nous vous remercions pour cela. Je n'avais pas vu la fonction de hachage auparavant, donc c'était une révélation. Même si une fausse correspondance est statistiquement insignifiante, y a-t-il un moyen d'utiliser la touche comme indice pour égaler des paragraphes, mais toujours utiliser la comparaison de phrases pour être complètement sûr? S'il vous plaît voir aussi ma mise à jour sur la sortie désirée. – mdma
@mdma - J'ai mis à jour mon message. En bref, vous pouvez filtrer les paragraphes qui n'ont aucune correspondance potentielle basée sur les deux colonnes int, puis calculer les hachés pour ceux qui ont une correspondance potentielle. – Thomas
Ma dernière requête était très similaire à ceci. J'ai aussi essayé de combiner cela avec INTERSECT pour éliminer les collisions de hachage et être sûr que les ensembles de phrases étaient vraiment égaux, mais le temps passé a pris de quelques secondes à plusieurs minutes (je ne l'ai jamais laissé terminer). référence les données réelles afin qu'elles soient uniques. – mdma