Other ACOS SQL function


1. Usage of ACOS to show hypothetical similiarity angles in degress of products

SQL Server Query 1

            
 WITH ProductData AS (  
SELECT
ProductID,
ProductName,
UnitPrice,
UnitsInStock,
-- Normalize UnitPrice and UnitsInStock to a range of 0 to 1
CAST(UnitPrice AS DECIMAL(10, 4)) / (SELECT MAX(UnitPrice) FROM Products) AS NormalizedPrice,
CAST(UnitsInStock AS DECIMAL(10, 4)) / (SELECT CAST(MAX(UnitsInStock) AS DECIMAL(10,4)) FROM Products) AS NormalizedStock
FROM Products
WHERE UnitsInStock > 0 AND UnitPrice > 0 --important to avoid nulls in normalization
),
ProductPairs AS (
SELECT
p1.ProductID AS Product1,
p1.ProductName AS ProductName1,
p2.ProductID AS Product2,
p2.ProductName AS ProductName2,
-- Calculate a value similar to cosine similarity (but with our normalized data)
(p1.NormalizedPrice * p2.NormalizedPrice + p1.NormalizedStock * p2.NormalizedStock) /
(
SQRT(p1.NormalizedPrice * p1.NormalizedPrice + p1.NormalizedStock * p1.NormalizedStock) *
SQRT(p2.NormalizedPrice * p2.NormalizedPrice + p2.NormalizedStock * p2.NormalizedStock)
) AS SimilarityValue
FROM ProductData p1
CROSS JOIN ProductData p2
WHERE p1.ProductID < p2.ProductID
),
AcosResult as (
SELECT
Product1,
ProductName1,
Product2,
ProductName2,
SimilarityValue,
-- Ensure the value is within the valid range for ACOS
CASE
WHEN SimilarityValue > 1 THEN 1
WHEN SimilarityValue < -1 THEN -1
ELSE SimilarityValue
END AS AdjustedSimilarityValue,
ACOS(
CASE
WHEN SimilarityValue > 1 THEN 1
WHEN SimilarityValue < -1 THEN -1
ELSE SimilarityValue
END
) AS SimilarityAngleInRadians
FROM ProductPairs

)
SELECT TOP 10
Product1,
ProductName1,
Product2,
ProductName2,
SimilarityAngleInRadians,
DEGREES(SimilarityAngleInRadians) AS SimilarityAngleInDegrees
FROM AcosResult
ORDER BY SimilarityAngleInRadians;

Create SQL query with SqlQueryBuilder 1

            
 var (sql1, parameters1) = new SqlQueryBuilder()  
.WithCTETable(new Table("ProductData"), new SqlQueryBuilder()
.Select()
.Columns("ProductID", "ProductName", "UnitPrice", "UnitsInStock")
.Column(new ColumnArithmatic()
.SqlFunction(new CAST(new Column("UnitPrice"), SqlDataType.DECIMAL, new Tuple<int, int>(10, 4)))
.DIVIDE()
.Column(new SqlQueryBuilder().Select()
.Column(new MAX(new Column("UnitPrice")), "NormalizedPrice")
.From("Products")
)
, "NormalizedPrice")
.Column(new ColumnArithmatic()
.SqlFunction(new CAST(new Column("UnitsInStock"), SqlDataType.DECIMAL, new Tuple<int, int>(10, 4)))
.DIVIDE()
.Column(new SqlQueryBuilder().Select()
.Column(new CAST(new MAX(new Column("UnitsInStock")), SqlDataType.DECIMAL, new Tuple<int, int>(10, 4)), "NormalizedStock")
.From("Products")
)
, "NormalizedStock")
.From("Products")
.Where(new Where(new Column("UnitsInStock").GreaterThan(0))
.AND(new Column("UnitPrice").GreaterThan(0)))
)
.WithCTETable(new Table("ProductPairs"), new SqlQueryBuilder()
.Select()
.Column("p1.ProductID", "Product1")
.Column("p1.ProductName", "ProductName1")
.Column("p2.ProductID", "Product2")
.Column("p2.ProductName", "ProductName2")
.Column(new ColumnArithmatic()
.StartBracket()
.Column("p1.NormalizedPrice").MULTIPLY().Column("p2.NormalizedPrice")
.ADD().Column("p1.NormalizedStock").MULTIPLY().Column("p2.NormalizedStock")
.EndBracket().DIVIDE()
.StartBracket()
.SqlFunction(new SQRT(new ColumnArithmatic().Column("p1.NormalizedPrice").MULTIPLY().Column("p1.NormalizedPrice").ADD()
.Column("p1.NormalizedStock").MULTIPLY().Column("p1.NormalizedStock")
)).MULTIPLY()
.SqlFunction(new SQRT(new ColumnArithmatic().Column("p2.NormalizedPrice").MULTIPLY().Column("p2.NormalizedPrice")
.ADD().Column("p2.NormalizedStock").MULTIPLY().Column("p2.NormalizedStock")
.EndBracket()
))
, "SimilarityValue")
.From("ProductData", "p1")
.Join(new List<IJoin>()
{
new CROSSJOIN().TableName(new Table("ProductData","p2"))
})
.Where(new Where(new Column("p1.ProductID").LessThan(new Column("p2.ProductID"))))
)
.WithCTETable(new Table("AcosResult"), new SqlQueryBuilder()
.Select()
.Columns("Product1", "ProductName1", "Product2", "ProductName2", "SimilarityValue")
.Column(new CASE()
.When(new Column("SimilarityValue").GreaterThan(1))
.Then(1)
.When(new Column("SimilarityValue").GreaterThan(-1))
.Then(-1)
.Else(new Column("SimilarityValue"))
, "AdjustedSimilarityValue")
.Column(new ACOS(new CASE()
.When(new Column("SimilarityValue").GreaterThan(1))
.Then(1)
.When(new Column("SimilarityValue").LessThan(-1))
.Then(-1)
.Else(new Column("SimilarityValue"))
)
, "SimilarityAngleInRadians")
.From("ProductPairs")
)
.Select().Top(10)
.Columns("Product1", "ProductName1", "Product2", "ProductName2", "SimilarityAngleInRadians")
.Column(new DEGREES(new Column("SimilarityAngleInRadians")), "SimilarityAngleInDegrees")
.From("AcosResult")
.OrderBy(new OrderBy().SetColumnAscending("SimilarityAngleInRadians"))
.Build();

Query build by SqlQueryBuilder 1

            
WITH ProductData
AS (SELECT ProductID,
           ProductName,
           UnitPrice,
           UnitsInStock,
           CAST (UnitPrice AS DECIMAL (10, 4)) / (SELECT MAX(UnitPrice) AS NormalizedPrice
                                                  FROM Products) AS NormalizedPrice,
           CAST (UnitsInStock AS DECIMAL (10, 4)) / (SELECT CAST (MAX(UnitsInStock) AS DECIMAL (10, 4)) AS NormalizedStock
                                                     FROM Products) AS NormalizedStock
    FROM Products
    WHERE UnitsInStock > @pMAIN_2507192031229020940
          AND UnitPrice > @pMAIN_2507192031229020941),
 ProductPairs
AS (SELECT p1.ProductID AS Product1,
           p1.ProductName AS ProductName1,
           p2.ProductID AS Product2,
           p2.ProductName AS ProductName2,
           (p1.NormalizedPrice * p2.NormalizedPrice + p1.NormalizedStock * p2.NormalizedStock) / (SQRT(p1.NormalizedPrice * p1.NormalizedPrice + p1.NormalizedStock * p1.NormalizedStock) * SQRT(p2.NormalizedPrice * p2.NormalizedPrice + p2.NormalizedStock * p2.NormalizedStock)) AS SimilarityValue
    FROM ProductData AS p1 CROSS JOIN ProductData AS p2
    WHERE p1.ProductID < p2.ProductID),
 AcosResult
AS (SELECT Product1,
           ProductName1,
           Product2,
           ProductName2,
           SimilarityValue,
           CASE WHEN SimilarityValue > @pMAIN_2507192031229020942 THEN @pMAIN_2507192031229020943 WHEN SimilarityValue > @pMAIN_2507192031229020944 THEN @pMAIN_2507192031229020945 ELSE SimilarityValue END AS AdjustedSimilarityValue,
           ACOS(CASE WHEN SimilarityValue > @pMAIN_2507192031229020946 THEN @pMAIN_2507192031229020947 WHEN SimilarityValue < @pMAIN_2507192031229020948 THEN @pMAIN_2507192031229020949 ELSE SimilarityValue END) AS SimilarityAngleInRadians
    FROM ProductPairs)
SELECT TOP 10 Product1,
              ProductName1,
              Product2,
              ProductName2,
              SimilarityAngleInRadians,
              DEGREES(SimilarityAngleInRadians) AS SimilarityAngleInDegrees
FROM AcosResult
ORDER BY SimilarityAngleInRadians ASC;


            
        

Parameters (If used)

Name Value
@pMAIN_2507192031229020940 0
@pMAIN_2507192031229020941 0
@pMAIN_2507192031229020942 1
@pMAIN_2507192031229020943 1
@pMAIN_2507192031229020944 -1
@pMAIN_2507192031229020945 -1
@pMAIN_2507192031229020946 1
@pMAIN_2507192031229020947 1
@pMAIN_2507192031229020948 -1
@pMAIN_2507192031229020949 -1

Query Results 1:

  Product1 ProductName1 Product2 ProductName2 SimilarityAngleInRadians SimilarityAngleInDegrees
1 10 Ikura 70 Outback Lager 0 0
2 13 Konbu 50 Valkoinen suklaa 0 0
3 25 NuNuCa Nuß-Nougat-Creme 52 Filo Mix 0 0
4 7 Uncle Bob's Organic Dried Pears 49 Maxilaku 0.000000021073424255447 0.00000120741826972573
5 34 Sasquatch Ale 46 Spegesild 0.0000896516979850368 0.00513666392072411
6 6 Grandma's Boysenberry Spread 55 Pâté chinois 0.000170212591084587 0.00975246308913292
7 26 Gumbär Gummibärchen 68 Scottish Longbreads 0.00032007904335472 0.0183391782948104
8 23 Tunnbröd 73 Röd Kaviar 0.000459719716187663 0.0263399994965051
9 40 Boston Crab Meat 73 Röd Kaviar 0.000509145312503459 0.0291718775653176
10 23 Tunnbröd 40 Boston Crab Meat 0.000968865028495687 0.0555118770506251


2. Usage of ACOS to show hypothetical relationship angles in radians of products

SQL Server Query 2

            
 WITH CustomerProductCounts AS (  
SELECT
c.CustomerID,
c.CompanyName AS CustomerName,
COUNT(DISTINCT od.ProductID) AS CustomerProductCount,
CAST(COUNT(DISTINCT od.ProductID) AS DECIMAL(10, 8)) / (SELECT MAX(sub.ProductCount) from (SELECT COUNT(DISTINCT od.ProductID) as ProductCount from Customers c join Orders o on c.CustomerID = o.CustomerID join [Order Details] od on o.OrderID = od.OrderID GROUP BY c.CustomerID) as sub) AS NormalizedCustomerProductCount
FROM Customers c
JOIN Orders o ON c.CustomerID = o.CustomerID
JOIN [Order Details] od ON o.OrderID = od.OrderID
GROUP BY c.CustomerID, c.CompanyName
),
SupplierProductCounts AS (
SELECT
s.SupplierID,
s.CompanyName AS SupplierName,
COUNT(DISTINCT p.ProductID) AS SupplierProductCount,
CAST(COUNT(DISTINCT p.ProductID) AS DECIMAL(10, 8)) / (SELECT MAX(SupplierProductCount) FROM (SELECT s.SupplierID, COUNT(DISTINCT p.ProductID) AS SupplierProductCount from Suppliers s JOIN Products p ON s.SupplierID = p.SupplierID GROUP BY s.SupplierID) as sub2) AS NormalizedSupplierProductCount
FROM Suppliers s
JOIN Products p ON s.SupplierID = p.SupplierID
GROUP BY s.SupplierID, s.CompanyName
),
CustomerSupplierPairs AS (
SELECT
cp.CustomerID,
cp.CustomerName,
sp.SupplierID,
sp.SupplierName,
-- Calculate a similarity value
(cp.NormalizedCustomerProductCount * sp.NormalizedSupplierProductCount) AS SimilarityValue
FROM CustomerProductCounts cp
CROSS JOIN SupplierProductCounts sp
WHERE cp.NormalizedCustomerProductCount > 0 AND sp.NormalizedSupplierProductCount > 0
),
AcosResult as (
SELECT
CustomerID,
CustomerName,
SupplierID,
SupplierName,
SimilarityValue,
CASE
WHEN SimilarityValue > 1 THEN 1
WHEN SimilarityValue < -1 THEN -1
ELSE SimilarityValue
END AS AdjustedSimilarityValue,
ACOS(
CASE
WHEN SimilarityValue > 1 THEN 1
WHEN SimilarityValue < -1 THEN -1
ELSE SimilarityValue
END
) AS RelationshipAngleInRadians
FROM CustomerSupplierPairs
)
SELECT TOP 10
CustomerID,
CustomerName,
SupplierID,
SupplierName,
RelationshipAngleInRadians,
DEGREES(RelationshipAngleInRadians) AS RelationshipAngleInDegrees
FROM AcosResult
ORDER BY RelationshipAngleInRadians;

Create SQL query with SqlQueryBuilder 2

            
 var (sql2, parameters2) = new SqlQueryBuilder()  
.WithCTETable(new Table("CustomerProductCounts"), new SqlQueryBuilder()
.Select()
.Column("c.CustomerID", "CustomerID")
.Column("c.CompanyName", "CustomerName")
.Column(new COUNT(new Column("od.ProductID"), true), "CustomerProductCount")
.Column(new ColumnArithmatic()
.SqlFunction(new CAST(new COUNT(new Column("od.ProductID"), true), SqlDataType.DECIMAL, new Tuple<int, int>(10, 8)))
.DIVIDE()
.Column(new SqlQueryBuilder()
.Select()
.Column(new MAX(new Column("sub.ProductCount")), "NormalizedCustomerProductCount")
.From(new SqlQueryBuilder()
.Select()
.Column(new COUNT(new Column("od.ProductID"), true), "ProductCount")
.From("Customers", "c")
.Join(new List<IJoin>()
{
new INNERJOIN().TableName(new Table("Orders","o"))
.On(new Column("c.CustomerID").Equale(new Column("o.CustomerID"))),
new INNERJOIN().TableName(new Table("[Order Details]","od"))
.On(new Column("o.OrderID").Equale(new Column("od.OrderID")))
})
.GroupBy(new GroupBy(new Column("c.CustomerID")))
, "sub")
)
, "NormalizedCustomerProductCount")
.From("Customers", "c")
.Join(new List<IJoin>()
{
new INNERJOIN().TableName(new Table("Orders","o"))
.On(new Column("c.CustomerID").Equale(new Column("o.CustomerID"))),
new INNERJOIN().TableName(new Table("[Order Details]","od"))
.On(new Column("o.OrderID").Equale(new Column("od.OrderID")))
})
.GroupBy(new GroupBy(new Column("c.CustomerID"), new Column("c.CompanyName")))
)
.WithCTETable(new Table("SupplierProductCounts"), new SqlQueryBuilder()
.Select()
.Column("s.SupplierID", "SupplierID")
.Column("s.CompanyName", "SupplierName")
.Column(new COUNT(new Column("p.ProductID"), true), "SupplierProductCount")
.Column(new ColumnArithmatic()
.SqlFunction(new CAST(new COUNT(new Column("p.ProductID"), true), SqlDataType.DECIMAL, new Tuple<int, int>(10, 8)))
.DIVIDE()
.Column(new SqlQueryBuilder().Select()
.Column(new MAX(new Column("SupplierProductCount")), "NormalizedSupplierProductCount")
.From(new SqlQueryBuilder()
.Select()
.Column("s.SupplierID", "SupplierID")
.Column(new COUNT(new Column("p.ProductID"), true), "SupplierProductCount")
.From("Suppliers", "s")
.Join(new List<IJoin>()
{
new INNERJOIN().TableName(new Table("Products","p"))
.On(new Column("s.SupplierID").Equale(new Column("p.SupplierID")))
})
.GroupBy(new GroupBy(new Column("s.SupplierID")))
, "sub2")
)
, "NormalizedSupplierProductCount")
.From("Suppliers", "s")
.Join(new List<IJoin>()
{
new INNERJOIN().TableName(new Table("Products","p"))
.On(new Column("s.SupplierID").Equale(new Column("p.SupplierID")))
})
.GroupBy(new GroupBy(new Column("s.SupplierID"), new Column("s.CompanyName")))
)
.WithCTETable(new Table("CustomerSupplierPairs"), new SqlQueryBuilder()
.Select()
.Columns("cp.CustomerID", "cp.CustomerName", "sp.SupplierID", "sp.SupplierName")
.Column(new ColumnArithmatic().StartBracket().Column("cp.NormalizedCustomerProductCount").MULTIPLY()
.Column("sp.NormalizedSupplierProductCount").EndBracket()
, "SimilarityValue")
.From("CustomerProductCounts", "cp")
.Join(new List<IJoin>()
{
new CROSSJOIN().TableName(new Table("SupplierProductCounts","sp"))
})
.Where(new Where(new Column("cp.NormalizedCustomerProductCount").GreaterThan(0))
.AND(new Column("sp.NormalizedSupplierProductCount").GreaterThan(0)))
)
.WithCTETable(new Table("AcosResult"), new SqlQueryBuilder()
.Select()
.Columns("CustomerID", "CustomerName", "SupplierID", "SupplierName", "SimilarityValue")
.Column(new CASE()
.When(new Column("SimilarityValue").GreaterThan(1))
.Then(1)
.When(new Column("SimilarityValue").LessThan(-1))
.Then(-1)
.Else(new Column("SimilarityValue"))
, "AdjustedSimilarityValue")
.Column(new ACOS(new CASE()
.When(new Column("SimilarityValue").GreaterThan(1))
.Then(1)
.When(new Column("SimilarityValue").LessThan(-1))
.Then(-1)
.Else(new Column("SimilarityValue")))
, "RelationshipAngleInRadians")
.From("CustomerSupplierPairs")
)
.Select().Top(10)
.Columns("CustomerID", "CustomerName", "SupplierID", "SupplierName", "RelationshipAngleInRadians")
.Column(new DEGREES(new Column("RelationshipAngleInRadians")), "RelationshipAngleInDegrees")
.From("AcosResult")
.OrderBy(new OrderBy().SetColumnAscending("RelationshipAngleInRadians"))
.Build();

Query build by SqlQueryBuilder 2

            
WITH CustomerProductCounts
AS (SELECT c.CustomerID AS CustomerID,
           c.CompanyName AS CustomerName,
           COUNT(DISTINCT od.ProductID) AS CustomerProductCount,
           CAST (COUNT(DISTINCT od.ProductID) AS DECIMAL (10, 8)) / (SELECT MAX(sub.ProductCount) AS NormalizedCustomerProductCount
                                                                     FROM (SELECT COUNT(DISTINCT od.ProductID) AS ProductCount
                                                                           FROM Customers AS c
                                                                                INNER JOIN
                                                                                Orders AS o
                                                                                ON c.CustomerID = o.CustomerID
                                                                                INNER JOIN
                                                                                [Order Details] AS od
                                                                                ON o.OrderID = od.OrderID
                                                                           GROUP BY c.CustomerID) AS sub) AS NormalizedCustomerProductCount
    FROM Customers AS c
         INNER JOIN
         Orders AS o
         ON c.CustomerID = o.CustomerID
         INNER JOIN
         [Order Details] AS od
         ON o.OrderID = od.OrderID
    GROUP BY c.CustomerID, c.CompanyName),
 SupplierProductCounts
AS (SELECT s.SupplierID AS SupplierID,
           s.CompanyName AS SupplierName,
           COUNT(DISTINCT p.ProductID) AS SupplierProductCount,
           CAST (COUNT(DISTINCT p.ProductID) AS DECIMAL (10, 8)) / (SELECT MAX(SupplierProductCount) AS NormalizedSupplierProductCount
                                                                    FROM (SELECT s.SupplierID AS SupplierID,
                                                                                 COUNT(DISTINCT p.ProductID) AS SupplierProductCount
                                                                          FROM Suppliers AS s
                                                                               INNER JOIN
                                                                               Products AS p
                                                                               ON s.SupplierID = p.SupplierID
                                                                          GROUP BY s.SupplierID) AS sub2) AS NormalizedSupplierProductCount
    FROM Suppliers AS s
         INNER JOIN
         Products AS p
         ON s.SupplierID = p.SupplierID
    GROUP BY s.SupplierID, s.CompanyName),
 CustomerSupplierPairs
AS (SELECT cp.CustomerID,
           cp.CustomerName,
           sp.SupplierID,
           sp.SupplierName,
           (cp.NormalizedCustomerProductCount * sp.NormalizedSupplierProductCount) AS SimilarityValue
    FROM CustomerProductCounts AS cp CROSS JOIN SupplierProductCounts AS sp
    WHERE cp.NormalizedCustomerProductCount > @pMAIN_2507192031229683260
          AND sp.NormalizedSupplierProductCount > @pMAIN_2507192031229683261),
 AcosResult
AS (SELECT CustomerID,
           CustomerName,
           SupplierID,
           SupplierName,
           SimilarityValue,
           CASE WHEN SimilarityValue > @pMAIN_2507192031229683262 THEN @pMAIN_2507192031229683263 WHEN SimilarityValue < @pMAIN_2507192031229683264 THEN @pMAIN_2507192031229683265 ELSE SimilarityValue END AS AdjustedSimilarityValue,
           ACOS(CASE WHEN SimilarityValue > @pMAIN_2507192031229683266 THEN @pMAIN_2507192031229683267 WHEN SimilarityValue < @pMAIN_2507192031229683268 THEN @pMAIN_2507192031229683269 ELSE SimilarityValue END) AS RelationshipAngleInRadians
    FROM CustomerSupplierPairs)
SELECT TOP 10 CustomerID,
              CustomerName,
              SupplierID,
              SupplierName,
              RelationshipAngleInRadians,
              DEGREES(RelationshipAngleInRadians) AS RelationshipAngleInDegrees
FROM AcosResult
ORDER BY RelationshipAngleInRadians ASC;


            
        

Parameters (If used)

Name Value
@pMAIN_2507192031229683260 0
@pMAIN_2507192031229683261 0
@pMAIN_2507192031229683262 1
@pMAIN_2507192031229683263 1
@pMAIN_2507192031229683264 -1
@pMAIN_2507192031229683265 -1
@pMAIN_2507192031229683266 1
@pMAIN_2507192031229683267 1
@pMAIN_2507192031229683268 -1
@pMAIN_2507192031229683269 -1

Query Results 2:

  CustomerID CustomerName SupplierId RelationshipAngleInRadians RelationshipAngleInDegrees
1 ERNSH Ernst Handel 7 0 0
2 ERNSH Ernst Handel 12 0 0
3 SAVEA Save-a-lot Markets 7 0.328806015570302 18.8391969706911
4 SAVEA Save-a-lot Markets 12 0.328806015570302 18.8391969706911
5 QUICK QUICK-Stop 7 0.505360510284157 28.9550243718598
6 QUICK QUICK-Stop 12 0.505360510284157 28.9550243718598
7 RATTC Rattlesnake Canyon Grocery 7 0.637524882148117 36.5274850816623
8 RATTC Rattlesnake Canyon Grocery 12 0.637524882148117 36.5274850816623
9 ERNSH Ernst Handel 2 0.643501108793284 36.869897645844
10 ERNSH Ernst Handel 8 0.643501108793284 36.869897645844