mirror of
https://github.com/Microsoft/sql-server-samples.git
synced 2025-12-08 14:58:54 +00:00
Remove extra spacing
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
# Implementing Transitive Closure Clustering in SQL Server using CLR UDF
|
||||
# Implementing Transitive Closure Clustering in SQL Server using CLR UDF
|
||||
SQL Database don't have built-in support for transitive closure clustering, so the only workaround is to implement this algorithm in .Net framework and expose it as T-SQL function.
|
||||
A discussion on the problem, the algorithm and a pure T-SQL based solution can be found here:
|
||||
A discussion on the problem, the algorithm and a pure T-SQL based solution can be found here:
|
||||
- [Transitive Closure Clustering with SQL Server, UDA and JSON](https://medium.com/@mauridb/transitive-closure-clustering-with-sql-server-uda-and-json-dade18953fd2)
|
||||
- [T-SQL Puzzle Challenge Grouping Connected Items](http://www.itprotoday.com/microsoft-sql-server/t-sql-puzzle-challenge-grouping-connected-items)
|
||||
|
||||
@@ -16,7 +16,7 @@ This code sample demonstrates how to create CLR User-Defined aggregate that impl
|
||||
|
||||
<a name=about-this-sample></a>
|
||||
|
||||
## About this sample
|
||||
## About this sample
|
||||
1. **Applies to:** SQL Server 2016+ Enterprise / Developer / Evaluation Edition
|
||||
2. **Key features:**
|
||||
- CLR, JSON
|
||||
@@ -52,9 +52,9 @@ GO
|
||||
CREATE SCHEMA TC;
|
||||
GO
|
||||
|
||||
CREATE AGGREGATE TC.CLUSTERING(@id1 INT, @id2 INT)
|
||||
RETURNS NVARCHAR(MAX)
|
||||
EXTERNAL NAME TransitiveClosure.[TransitiveClosure.Aggregate];
|
||||
CREATE AGGREGATE TC.CLUSTERING(@id1 INT, @id2 INT)
|
||||
RETURNS NVARCHAR(MAX)
|
||||
EXTERNAL NAME TransitiveClosure.[TransitiveClosure.Aggregate];
|
||||
```
|
||||
|
||||
This code will import assembly in SQL Database and add an aggregate that provides clustering functionalities.
|
||||
@@ -69,7 +69,7 @@ Once you create the assembly and expose the aggregate, you can use it to cluster
|
||||
declare @edges table(n1 int, n2 int);
|
||||
|
||||
insert into @edges
|
||||
values
|
||||
values
|
||||
(1,2),(2,3),(3,4),(4,5),(2,21),(2,22),
|
||||
(7,8),(8,9),(9,10);
|
||||
|
||||
|
||||
@@ -18,6 +18,6 @@ GO
|
||||
CREATE SCHEMA TC;
|
||||
GO
|
||||
|
||||
CREATE AGGREGATE TC.CLUSTERING(@id1 INT, @id2 INT)
|
||||
RETURNS NVARCHAR(MAX)
|
||||
CREATE AGGREGATE TC.CLUSTERING(@id1 INT, @id2 INT)
|
||||
RETURNS NVARCHAR(MAX)
|
||||
EXTERNAL NAME TransitiveClosure.[TransitiveClosure.Aggregate];
|
||||
@@ -14,7 +14,7 @@ namespace TransitiveClosure
|
||||
public class Group: IEnumerable<int>
|
||||
{
|
||||
private int? _groupRoot = null;
|
||||
|
||||
|
||||
private Dictionary<int, bool> _group = new Dictionary<int, bool>();
|
||||
public Dictionary<int, bool>.KeyCollection Elements => _group.Keys;
|
||||
public int Count => _group.Keys.Count;
|
||||
@@ -31,12 +31,12 @@ namespace TransitiveClosure
|
||||
/// <param name="to"></param>
|
||||
public void AddUnique(int from, int to)
|
||||
{
|
||||
if (_groupRoot == null) _groupRoot = from;
|
||||
if (_groupRoot == null) _groupRoot = from;
|
||||
this.AddIfNotExists(from);
|
||||
this.AddIfNotExists(to);
|
||||
}
|
||||
/// <summary>
|
||||
/// Adds the element into the current group.
|
||||
/// Adds the element into the current group.
|
||||
/// </summary>
|
||||
/// <param name="element">The number that should be added.</param>
|
||||
public void Add(int element)
|
||||
@@ -46,7 +46,7 @@ namespace TransitiveClosure
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds the element to a group if it is not already there.
|
||||
/// Adds the element to a group if it is not already there.
|
||||
/// </summary>
|
||||
/// <param name="element"></param>
|
||||
public void AddIfNotExists(int element)
|
||||
@@ -111,11 +111,11 @@ namespace TransitiveClosure
|
||||
public List<Group> FindInGroups(int from, int to)
|
||||
{
|
||||
var result = new List<Group>();
|
||||
|
||||
|
||||
if (_numbers.ContainsKey(from)) result.Add(_numbers[from]);
|
||||
if (_numbers.ContainsKey(to)) result.Add(_numbers[to]);
|
||||
|
||||
return result;
|
||||
return result;
|
||||
}
|
||||
|
||||
public void AddPair(int from, int to)
|
||||
@@ -123,7 +123,7 @@ namespace TransitiveClosure
|
||||
//Find if the inputValue is already in a group
|
||||
var foundInGroups = FindInGroups(from, to);
|
||||
|
||||
// no item matches: create a new group and add both the values to it
|
||||
// no item matches: create a new group and add both the values to it
|
||||
if (foundInGroups.Count == 0)
|
||||
{
|
||||
var ng = new Group();
|
||||
@@ -166,7 +166,7 @@ namespace TransitiveClosure
|
||||
if (!_numbers.ContainsKey(from)) _numbers.Add(from, g1); else _numbers[from] = g1;
|
||||
if (!_numbers.ContainsKey(to)) _numbers.Add(to, g1); else _numbers[to] = g1;
|
||||
|
||||
g1.MergeWith(g2);
|
||||
g1.MergeWith(g2);
|
||||
|
||||
foreach(var e in g2)
|
||||
{
|
||||
@@ -219,7 +219,7 @@ namespace TransitiveClosure
|
||||
|
||||
public void Accumulate(int inputValue1, int inputValue2)
|
||||
{
|
||||
_groupSet.AddPair(inputValue1, inputValue2);
|
||||
_groupSet.AddPair(inputValue1, inputValue2);
|
||||
}
|
||||
|
||||
public void Merge(Aggregate value)
|
||||
@@ -236,7 +236,7 @@ namespace TransitiveClosure
|
||||
pe = ce;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public SqlString Terminate()
|
||||
{
|
||||
@@ -256,7 +256,7 @@ namespace TransitiveClosure
|
||||
g.Elements.CopyTo(ea, 0);
|
||||
|
||||
sb.Append(string.Join(",", ea));
|
||||
|
||||
|
||||
sb.Append("],");
|
||||
|
||||
c += 1;
|
||||
@@ -277,7 +277,7 @@ namespace TransitiveClosure
|
||||
// For Each Group
|
||||
for (int j = 0; j < g; j++)
|
||||
{
|
||||
var l = new Group();
|
||||
var l = new Group();
|
||||
|
||||
// List Size (or Values Count)
|
||||
int s = r.ReadInt32();
|
||||
|
||||
Reference in New Issue
Block a user