COUNT SQL function
1. Usage of COUNT to find customer distribution within country
SQL Server Query 1
WITH CustomerOrderCounts AS (
SELECT
c.CustomerID,
c.CompanyName,
c.Country,
COUNT(o.OrderID) AS TotalOrders
FROM
Customers c
LEFT JOIN
Orders o ON c.CustomerID = o.CustomerID
GROUP BY
c.CustomerID,
c.CompanyName,
c.Country
),
CountryOrderDistribution AS (
SELECT
Country,
TotalOrders,
CUME_DIST() OVER (PARTITION BY Country ORDER BY TotalOrders) + 1 AS CumulativeDistributionWithinCountry
FROM
CustomerOrderCounts
)
SELECT
coc.CustomerID,
coc.CompanyName,
coc.Country,
coc.TotalOrders,
cod.CumulativeDistributionWithinCountry
FROM
CustomerOrderCounts coc
JOIN
CountryOrderDistribution cod ON coc.Country = cod.Country AND coc.TotalOrders = cod.TotalOrders
ORDER BY
coc.Country,
cod.CumulativeDistributionWithinCountry;
Create SQL query with SqlQueryBuilder 1
var (sql1, parameters1) = new SqlQueryBuilder()
.WithCTETable(new Table("CustomerOrderCounts"), new SqlQueryBuilder()
.Select()
.Columns("c.CustomerID", "c.CompanyName", "c.Country")
.Column(new COUNT(new Column("o.OrderId")), "TotalOrders")
.From("Customers", "c")
.Join(new List<IJoin>()
{
new LEFTJOIN().TableName(new Table("Orders","o"))
.On(new Column("c.CustomerID").Equale(new Column("o.CustomerID")))
})
.GroupBy(new GroupBy("c.CustomerID", "c.CompanyName", "c.Country"))
)
.WithCTETable(new Table("CountryOrderDistribution"), new SqlQueryBuilder()
.Select()
.Columns("Country", "TotalOrders")
.Column(new CUME_DIST().PARTITION_BY(new Column("Country")).ORDER_BY(new OrderBy().Set(new Column("TotalOrders"))
).AddArithmatic(new Arithmatic().Add(1)), "CumulativeDistributionWithinCountry")
.From("CustomerOrderCounts")
)
.Select()
.Columns("coc.CustomerID", "coc.CompanyName", "coc.Country", "coc.TotalOrders", "cod.CumulativeDistributionWithinCountry")
.From("CustomerOrderCounts", "coc")
.Join(new List<IJoin>()
{
new INNERJOIN().TableName(new Table("CountryOrderDistribution","cod"))
.On(new Column("coc.Country").Equale(new Column("cod.Country")))
.AND(new Column("coc.TotalOrders").Equale(new Column("cod.TotalOrders")))
})
.OrderBy(new OrderBy().Set(new Column("coc.Country")).Set(new Column("cod.CumulativeDistributionWithinCountry")))
.Build();
Query build by SqlQueryBuilder 1
WITH CustomerOrderCounts
AS (SELECT c.CustomerID,
c.CompanyName,
c.Country,
COUNT(o.OrderId) AS TotalOrders
FROM Customers AS c
LEFT OUTER JOIN
Orders AS o
ON c.CustomerID = o.CustomerID
GROUP BY c.CustomerID, c.CompanyName, c.Country),
CountryOrderDistribution
AS (SELECT Country,
TotalOrders,
CUME_DIST() OVER (PARTITION BY Country ORDER BY TotalOrders ASC) + @pMAIN_2512060920293783740 AS CumulativeDistributionWithinCountry
FROM CustomerOrderCounts)
SELECT coc.CustomerID,
coc.CompanyName,
coc.Country,
coc.TotalOrders,
cod.CumulativeDistributionWithinCountry
FROM CustomerOrderCounts AS coc
INNER JOIN
CountryOrderDistribution AS cod
ON coc.Country = cod.Country
AND coc.TotalOrders = cod.TotalOrders
ORDER BY coc.Country ASC, cod.CumulativeDistributionWithinCountry ASC;
Parameters (If used)
| Name |
Value |
| @pMAIN_2512060920293783740 |
1 |
Query Results 1:
| |
CustomerID |
CompanyName |
Country |
TotalOrders |
CumulativeDistributionWithinCountry |
CumulativeDistribution |
| 1 |
OCEAN
|
Océano Atlántico Ltda.
|
Argentina
|
5
|
1.66666666666667
|
0
|
| 2 |
OCEAN
|
Océano Atlántico Ltda.
|
Argentina
|
5
|
1.66666666666667
|
0
|
| 3 |
RANCH
|
Rancho grande
|
Argentina
|
5
|
1.66666666666667
|
0
|
| 4 |
RANCH
|
Rancho grande
|
Argentina
|
5
|
1.66666666666667
|
0
|
| 5 |
CACTU
|
Cactus Comidas para llevar
|
Argentina
|
6
|
2
|
0
|
| 6 |
PICCO
|
Piccolo und mehr
|
Austria
|
10
|
1.5
|
0
|
| 7 |
ERNSH
|
Ernst Handel
|
Austria
|
30
|
2
|
0
|
| 8 |
MAISD
|
Maison Dewey
|
Belgium
|
7
|
1.5
|
0
|
| 9 |
SUPRD
|
Suprêmes délices
|
Belgium
|
12
|
2
|
0
|
| 10 |
COMMI
|
Comércio Mineiro
|
Brazil
|
5
|
1.11111111111111
|
0
|
| 11 |
TRADH
|
Tradição Hipermercados
|
Brazil
|
6
|
1.22222222222222
|
0
|
| 12 |
FAMIA
|
Familia Arquibaldo
|
Brazil
|
7
|
1.33333333333333
|
0
|
| 13 |
GOURL
|
Gourmet Lanchonetes
|
Brazil
|
9
|
1.66666666666667
|
0
|
| 14 |
GOURL
|
Gourmet Lanchonetes
|
Brazil
|
9
|
1.66666666666667
|
0
|
| 15 |
GOURL
|
Gourmet Lanchonetes
|
Brazil
|
9
|
1.66666666666667
|
0
|
| 16 |
QUEDE
|
Que Delícia
|
Brazil
|
9
|
1.66666666666667
|
0
|
| 17 |
QUEDE
|
Que Delícia
|
Brazil
|
9
|
1.66666666666667
|
0
|
| 18 |
QUEDE
|
Que Delícia
|
Brazil
|
9
|
1.66666666666667
|
0
|
| 19 |
WELLI
|
Wellington Importadora
|
Brazil
|
9
|
1.66666666666667
|
0
|
| 20 |
WELLI
|
Wellington Importadora
|
Brazil
|
9
|
1.66666666666667
|
0
|
| 21 |
WELLI
|
Wellington Importadora
|
Brazil
|
9
|
1.66666666666667
|
0
|
| 22 |
RICAR
|
Ricardo Adocicados
|
Brazil
|
11
|
1.77777777777778
|
0
|
| 23 |
QUEEN
|
Queen Cozinha
|
Brazil
|
13
|
1.88888888888889
|
0
|
| 24 |
HANAR
|
Hanari Carnes
|
Brazil
|
14
|
2
|
0
|
| 25 |
LAUGB
|
Laughing Bacchus Wine Cellars
|
Canada
|
3
|
1.33333333333333
|
0
|
| 26 |
MEREP
|
Mère Paillarde
|
Canada
|
13
|
1.66666666666667
|
0
|
| 27 |
BOTTM
|
Bottom-Dollar Markets
|
Canada
|
14
|
2
|
0
|
| 28 |
SIMOB
|
Simons bistro
|
Denmark
|
7
|
1.5
|
0
|
| 29 |
VAFFE
|
Vaffeljernet
|
Denmark
|
11
|
2
|
0
|
| 30 |
WILMK
|
Wilman Kala
|
Finland
|
7
|
1.5
|
0
|
| 31 |
WARTH
|
Wartian Herkku
|
Finland
|
15
|
2
|
0
|
| 32 |
PARIS
|
Paris spécialités
|
France
|
0
|
1.09090909090909
|
0
|
| 33 |
FRANR
|
France restauration
|
France
|
3
|
1.18181818181818
|
0
|
| 34 |
DUMON
|
Du monde entier
|
France
|
4
|
1.45454545454545
|
0
|
| 35 |
DUMON
|
Du monde entier
|
France
|
4
|
1.45454545454545
|
0
|
| 36 |
DUMON
|
Du monde entier
|
France
|
4
|
1.45454545454545
|
0
|
| 37 |
LACOR
|
La corne d'abondance
|
France
|
4
|
1.45454545454545
|
0
|
| 38 |
LACOR
|
La corne d'abondance
|
France
|
4
|
1.45454545454545
|
0
|
| 39 |
LACOR
|
La corne d'abondance
|
France
|
4
|
1.45454545454545
|
0
|
| 40 |
SPECD
|
Spécialités du monde
|
France
|
4
|
1.45454545454545
|
0
|
| 41 |
SPECD
|
Spécialités du monde
|
France
|
4
|
1.45454545454545
|
0
|
| 42 |
SPECD
|
Spécialités du monde
|
France
|
4
|
1.45454545454545
|
0
|
| 43 |
VINET
|
Vins et alcools Chevalier
|
France
|
5
|
1.63636363636364
|
0
|
| 44 |
VINET
|
Vins et alcools Chevalier
|
France
|
5
|
1.63636363636364
|
0
|
| 45 |
FOLIG
|
Folies gourmandes
|
France
|
5
|
1.63636363636364
|
0
|
| 46 |
FOLIG
|
Folies gourmandes
|
France
|
5
|
1.63636363636364
|
0
|
| 47 |
VICTE
|
Victuailles en stock
|
France
|
10
|
1.72727272727273
|
0
|
| 48 |
BLONP
|
Blondesddsl père et fils
|
France
|
11
|
1.81818181818182
|
0
|
| 49 |
LAMAI
|
La maison d'Asie
|
France
|
14
|
1.90909090909091
|
0
|
| 50 |
BONAP
|
Bon app'
|
France
|
17
|
2
|
0
|
| 51 |
MORGK
|
Morgenstern Gesundkost
|
Germany
|
5
|
1.09090909090909
|
0
|
| 52 |
ALFKI
|
Alfreds Futterkiste
|
Germany
|
6
|
1.36363636363636
|
0
|
| 53 |
ALFKI
|
Alfreds Futterkiste
|
Germany
|
6
|
1.36363636363636
|
0
|
| 54 |
ALFKI
|
Alfreds Futterkiste
|
Germany
|
6
|
1.36363636363636
|
0
|
| 55 |
DRACD
|
Drachenblut Delikatessen
|
Germany
|
6
|
1.36363636363636
|
0
|
| 56 |
DRACD
|
Drachenblut Delikatessen
|
Germany
|
6
|
1.36363636363636
|
0
|
| 57 |
DRACD
|
Drachenblut Delikatessen
|
Germany
|
6
|
1.36363636363636
|
0
|
| 58 |
TOMSP
|
Toms Spezialitäten
|
Germany
|
6
|
1.36363636363636
|
0
|
| 59 |
TOMSP
|
Toms Spezialitäten
|
Germany
|
6
|
1.36363636363636
|
0
|
| 60 |
TOMSP
|
Toms Spezialitäten
|
Germany
|
6
|
1.36363636363636
|
0
|
| 61 |
BLAUS
|
Blauer See Delikatessen
|
Germany
|
7
|
1.45454545454545
|
0
|
| 62 |
OTTIK
|
Ottilies Käseladen
|
Germany
|
10
|
1.63636363636364
|
0
|
| 63 |
OTTIK
|
Ottilies Käseladen
|
Germany
|
10
|
1.63636363636364
|
0
|
| 64 |
WANDK
|
Die Wandernde Kuh
|
Germany
|
10
|
1.63636363636364
|
0
|
| 65 |
WANDK
|
Die Wandernde Kuh
|
Germany
|
10
|
1.63636363636364
|
0
|
| 66 |
KOENE
|
Königlich Essen
|
Germany
|
14
|
1.72727272727273
|
0
|
| 67 |
FRANK
|
Frankenversand
|
Germany
|
15
|
1.90909090909091
|
0
|
| 68 |
FRANK
|
Frankenversand
|
Germany
|
15
|
1.90909090909091
|
0
|
| 69 |
LEHMS
|
Lehmanns Marktstand
|
Germany
|
15
|
1.90909090909091
|
0
|
| 70 |
LEHMS
|
Lehmanns Marktstand
|
Germany
|
15
|
1.90909090909091
|
0
|
| 71 |
QUICK
|
QUICK-Stop
|
Germany
|
28
|
2
|
0
|
| 72 |
HUNGO
|
Hungry Owl All-Night Grocers
|
Ireland
|
19
|
2
|
0
|
| 73 |
FRANS
|
Franchi S.p.A.
|
Italy
|
6
|
1.33333333333333
|
0
|
| 74 |
MAGAA
|
Magazzini Alimentari Riuniti
|
Italy
|
10
|
1.66666666666667
|
0
|
| 75 |
REGGC
|
Reggiani Caseifici
|
Italy
|
12
|
2
|
0
|
| 76 |
CENTC
|
Centro comercial Moctezuma
|
Mexico
|
1
|
1.2
|
0
|
| 77 |
ANATR
|
Ana Trujillo Emparedados y helados
|
Mexico
|
4
|
1.4
|
0
|
| 78 |
PERIC
|
Pericles Comidas clásicas
|
Mexico
|
6
|
1.6
|
0
|
| 79 |
ANTON
|
Antonio Moreno Taquería
|
Mexico
|
7
|
1.8
|
0
|
| 80 |
TORTU
|
Tortuga Restaurante
|
Mexico
|
10
|
2
|
0
|
| 81 |
SANTG
|
Santé Gourmet
|
Norway
|
6
|
2
|
0
|
| 82 |
WOLZA
|
Wolski Zajazd
|
Poland
|
7
|
2
|
0
|
| 83 |
PRINI
|
Princesa Isabel Vinhos
|
Portugal
|
5
|
1.5
|
0
|
| 84 |
FURIB
|
Furia Bacalhau e Frutos do Mar
|
Portugal
|
8
|
2
|
0
|
| 85 |
FISSA
|
FISSA Fabrica Inter. Salchichas S.A.
|
Spain
|
0
|
1.2
|
0
|
| 86 |
BOLID
|
Bólido Comidas preparadas
|
Spain
|
3
|
1.4
|
0
|
| 87 |
GALED
|
Galería del gastrónomo
|
Spain
|
5
|
1.8
|
0
|
| 88 |
GALED
|
Galería del gastrónomo
|
Spain
|
5
|
1.8
|
0
|
| 89 |
ROMEY
|
Romero y tomillo
|
Spain
|
5
|
1.8
|
0
|
| 90 |
ROMEY
|
Romero y tomillo
|
Spain
|
5
|
1.8
|
0
|
| 91 |
GODOS
|
Godos Cocina Típica
|
Spain
|
10
|
2
|
0
|
| 92 |
BERGS
|
Berglunds snabbköp
|
Sweden
|
18
|
1.5
|
0
|
| 93 |
FOLKO
|
Folk och fä HB
|
Sweden
|
19
|
2
|
0
|
| 94 |
CHOPS
|
Chop-suey Chinese
|
Switzerland
|
8
|
1.5
|
0
|
| 95 |
RICSU
|
Richter Supermarkt
|
Switzerland
|
10
|
2
|
0
|
| 96 |
CONSH
|
Consolidated Holdings
|
UK
|
3
|
1.28571428571429
|
0
|
| 97 |
CONSH
|
Consolidated Holdings
|
UK
|
3
|
1.28571428571429
|
0
|
| 98 |
NORTS
|
North/South
|
UK
|
3
|
1.28571428571429
|
0
|
| 99 |
NORTS
|
North/South
|
UK
|
3
|
1.28571428571429
|
0
|
| 100 |
EASTC
|
Eastern Connection
|
UK
|
8
|
1.42857142857143
|
0
|
| 101 |
SEVES
|
Seven Seas Imports
|
UK
|
9
|
1.57142857142857
|
0
|
| 102 |
BSBEV
|
B's Beverages
|
UK
|
10
|
1.85714285714286
|
0
|
| 103 |
BSBEV
|
B's Beverages
|
UK
|
10
|
1.85714285714286
|
0
|
| 104 |
ISLAT
|
Island Trading
|
UK
|
10
|
1.85714285714286
|
0
|
| 105 |
ISLAT
|
Island Trading
|
UK
|
10
|
1.85714285714286
|
0
|
| 106 |
AROUT
|
Around the Horn
|
UK
|
13
|
2
|
0
|
| 107 |
LAZYK
|
Lazy K Kountry Store
|
USA
|
2
|
1.07692307692308
|
0
|
| 108 |
TRAIH
|
Trail's Head Gourmet Provisioners
|
USA
|
3
|
1.23076923076923
|
0
|
| 109 |
TRAIH
|
Trail's Head Gourmet Provisioners
|
USA
|
3
|
1.23076923076923
|
0
|
| 110 |
THECR
|
The Cracker Box
|
USA
|
3
|
1.23076923076923
|
0
|
| 111 |
THECR
|
The Cracker Box
|
USA
|
3
|
1.23076923076923
|
0
|
| 112 |
THEBI
|
The Big Cheese
|
USA
|
4
|
1.38461538461538
|
0
|
| 113 |
THEBI
|
The Big Cheese
|
USA
|
4
|
1.38461538461538
|
0
|
| 114 |
LETSS
|
Let's Stop N Shop
|
USA
|
4
|
1.38461538461538
|
0
|
| 115 |
LETSS
|
Let's Stop N Shop
|
USA
|
4
|
1.38461538461538
|
0
|
| 116 |
HUNGC
|
Hungry Coyote Import Store
|
USA
|
5
|
1.46153846153846
|
0
|
| 117 |
LONEP
|
Lonesome Pine Restaurant
|
USA
|
8
|
1.53846153846154
|
0
|
| 118 |
SPLIR
|
Split Rail Beer & Ale
|
USA
|
9
|
1.61538461538462
|
0
|
| 119 |
OLDWO
|
Old World Delicatessen
|
USA
|
10
|
1.69230769230769
|
0
|
| 120 |
GREAL
|
Great Lakes Food Market
|
USA
|
11
|
1.76923076923077
|
0
|
| 121 |
WHITC
|
White Clover Markets
|
USA
|
14
|
1.84615384615385
|
0
|
| 122 |
RATTC
|
Rattlesnake Canyon Grocery
|
USA
|
18
|
1.92307692307692
|
0
|
| 123 |
SAVEA
|
Save-a-lot Markets
|
USA
|
31
|
2
|
0
|
| 124 |
GROSR
|
GROSELLA-Restaurante
|
Venezuela
|
2
|
1.25
|
0
|
| 125 |
LINOD
|
LINO-Delicateses
|
Venezuela
|
12
|
1.5
|
0
|
| 126 |
LILAS
|
LILA-Supermercado
|
Venezuela
|
14
|
1.75
|
0
|
| 127 |
HILAA
|
HILARION-Abastos
|
Venezuela
|
18
|
2
|
0
|
2. Usage of COUNT with DISTINCT find customer suppliers
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").Equale(0))
.AND(new Column("sp.NormalizedSupplierProductCount").Equale(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").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").GreaterThan(-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_2512060920293933940
AND sp.NormalizedSupplierProductCount > @pMAIN_2512060920293933941),
AcosResult
AS (SELECT CustomerID,
CustomerName,
SupplierID,
SupplierName,
SimilarityValue,
CASE WHEN SimilarityValue > @pMAIN_2512060920293933942 THEN @pMAIN_2512060920293933943 WHEN SimilarityValue > @pMAIN_2512060920293933944 THEN @pMAIN_2512060920293933945 ELSE SimilarityValue END AS AdjustedSimilarityValue,
ACOS(CASE WHEN SimilarityValue > @pMAIN_2512060920293933946 THEN @pMAIN_2512060920293933947 WHEN SimilarityValue > @pMAIN_2512060920293933948 THEN @pMAIN_2512060920293933949 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_2512060920293933940 |
0 |
| @pMAIN_2512060920293933941 |
0 |
| @pMAIN_2512060920293933942 |
1 |
| @pMAIN_2512060920293933943 |
1 |
| @pMAIN_2512060920293933944 |
-1 |
| @pMAIN_2512060920293933945 |
-1 |
| @pMAIN_2512060920293933946 |
1 |
| @pMAIN_2512060920293933947 |
1 |
| @pMAIN_2512060920293933948 |
-1 |
| @pMAIN_2512060920293933949 |
-1 |
Query Results 2:
| |
CustomerID |
CustomerName |
SupplierId |
SupplierName |
RelationshipAngleInRadians |
RelationshipAngleInDegrees |
| 1 |
ALFKI
|
Alfreds Futterkiste
|
11
|
Heli Süßwaren GmbH & Co. KG
|
3.14159265358979
|
180
|
| 2 |
ALFKI
|
Alfreds Futterkiste
|
10
|
Refrescos Americanas LTDA
|
3.14159265358979
|
180
|
| 3 |
ALFKI
|
Alfreds Futterkiste
|
9
|
PB Knäckebröd AB
|
3.14159265358979
|
180
|
| 4 |
ALFKI
|
Alfreds Futterkiste
|
8
|
Specialty Biscuits, Ltd.
|
3.14159265358979
|
180
|
| 5 |
ALFKI
|
Alfreds Futterkiste
|
7
|
Pavlova, Ltd.
|
3.14159265358979
|
180
|
| 6 |
ALFKI
|
Alfreds Futterkiste
|
6
|
Mayumi's
|
3.14159265358979
|
180
|
| 7 |
ALFKI
|
Alfreds Futterkiste
|
5
|
Cooperativa de Quesos 'Las Cabras'
|
3.14159265358979
|
180
|
| 8 |
ALFKI
|
Alfreds Futterkiste
|
4
|
Tokyo Traders
|
3.14159265358979
|
180
|
| 9 |
ALFKI
|
Alfreds Futterkiste
|
3
|
Grandma Kelly's Homestead
|
3.14159265358979
|
180
|
| 10 |
ALFKI
|
Alfreds Futterkiste
|
2
|
New Orleans Cajun Delights
|
3.14159265358979
|
180
|