SELECT with OPTION Hints
6. Sales Report with Forced Join Order
SQL Server Query 1
-- Advanced Query: Sales Report with Forced Join Order
SELECT
C.CompanyName,
Cat.CategoryName,
SUM(OD.Quantity * OD.UnitPrice * (1 - OD.Discount)) AS TotalCategorySales
FROM Customers AS C -- 1st in join order (outermost)
JOIN Orders AS O ON C.CustomerID = O.CustomerID -- 2nd
JOIN [Order Details] AS OD ON O.OrderID = OD.OrderID -- 3rd
JOIN Products AS P ON OD.ProductID = P.ProductID -- 4th
JOIN Categories AS Cat ON P.CategoryID = Cat.CategoryID -- 5th (innermost)
WHERE C.Country = 'USA'
AND O.OrderDate >= '1997-01-01'
GROUP BY C.CompanyName, Cat.CategoryName
ORDER BY C.CompanyName, Cat.CategoryName
OPTION (FORCE ORDER); -- Forces the optimizer to join tables in the FROM clause order
Create SQL query with SqlQueryBuilder 1
var (sql6, parameters6) = new SqlQueryBuilder()
.Select()
.Columns("C.CompanyName","Cat.CategoryName")
.Column(new SUM(new ColumnArithmatic("OD.Quantity").MULTIPLY("OD.UnitPrice")
.MULTIPLY().StartBracket(1).SUBTRACT("OD.Discount").EndBracket()), "TotalCategorySales")
.From("Customers", "C")
.Join(new List<IJoin>()
{
new INNERJOIN().TableName("Orders","O")
.On(new Column("C.CustomerID").Equale(new Column("O.CustomerID"))),
new INNERJOIN().TableName("[Order Details]","OD")
.On(new Column("O.OrderID").Equale(new Column("OD.OrderID"))),
new INNERJOIN().TableName("Products","P")
.On(new Column("OD.ProductID").Equale(new Column("P.ProductID"))),
new INNERJOIN().TableName("Categories", "Cat")
.On(new Column("P.CategoryID").Equale(new Column("Cat.CategoryID")))
})
.Where(new Where(new Column("C.Country").Equale("USA"))
.AND(new Column("O.OrderDate").GreaterThanOrEqualeTo("1997-01-01")))
.GroupBy(new GroupBy("C.CompanyName","Cat.CategoryName"))
.OrderBy(new OrderBy().SetColumnAscending("C.CompanyName")
.SetColumnAscending("Cat.CategoryName"))
.Option(new List<IOption>() { new FORCE_ORDER() })
.Build();
Query build by SqlQueryBuilder 1
SELECT C.CompanyName,
Cat.CategoryName,
SUM(OD.Quantity * OD.UnitPrice * (@pMAIN_2507192011455121520 - OD.Discount)) AS TotalCategorySales
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
INNER JOIN
Products AS P
ON OD.ProductID = P.ProductID
INNER JOIN
Categories AS Cat
ON P.CategoryID = Cat.CategoryID
WHERE C.Country = @pMAIN_2507192011455121521
AND O.OrderDate >= @pMAIN_2507192011455121522
GROUP BY C.CompanyName, Cat.CategoryName
ORDER BY C.CompanyName ASC, Cat.CategoryName ASC
OPTION (FORCE ORDER);
Parameters (If used)
Name |
Value |
@pMAIN_2507192011455121520 |
1 |
@pMAIN_2507192011455121521 |
USA |
@pMAIN_2507192011455121522 |
1997-01-01 |
Query Results 1:
|
CompanyName |
CategoryName |
TotalCategorySales |
1 |
Great Lakes Food Market
|
Beverages
|
11694.375
|
2 |
Great Lakes Food Market
|
Condiments
|
490.139953613281
|
3 |
Great Lakes Food Market
|
Confections
|
1544.40000534058
|
4 |
Great Lakes Food Market
|
Dairy Products
|
2611.07501220703
|
5 |
Great Lakes Food Market
|
Grains/Cereals
|
1463
|
6 |
Great Lakes Food Market
|
Meat/Poultry
|
185.684997558594
|
7 |
Great Lakes Food Market
|
Produce
|
62.7749977111816
|
8 |
Great Lakes Food Market
|
Seafood
|
456
|
9 |
Hungry Coyote Import Store
|
Confections
|
1701
|
10 |
Hungry Coyote Import Store
|
Dairy Products
|
40
|
11 |
Hungry Coyote Import Store
|
Meat/Poultry
|
92.2000007629394
|
12 |
Hungry Coyote Import Store
|
Seafood
|
450
|
13 |
Lazy K Kountry Store
|
Dairy Products
|
210
|
14 |
Lazy K Kountry Store
|
Seafood
|
147
|
15 |
Let's Stop N Shop
|
Beverages
|
162.75
|
16 |
Let's Stop N Shop
|
Condiments
|
931.370000839234
|
17 |
Let's Stop N Shop
|
Confections
|
380
|
18 |
Let's Stop N Shop
|
Grains/Cereals
|
758.099975585938
|
19 |
Let's Stop N Shop
|
Meat/Poultry
|
223.5
|
20 |
Let's Stop N Shop
|
Seafood
|
620.752498626709
|
21 |
Lonesome Pine Restaurant
|
Beverages
|
314
|
22 |
Lonesome Pine Restaurant
|
Confections
|
125
|
23 |
Lonesome Pine Restaurant
|
Dairy Products
|
815
|
24 |
Lonesome Pine Restaurant
|
Grains/Cereals
|
190
|
25 |
Lonesome Pine Restaurant
|
Meat/Poultry
|
98.4000015258789
|
26 |
Lonesome Pine Restaurant
|
Produce
|
1379.20001220703
|
27 |
Lonesome Pine Restaurant
|
Seafood
|
625
|
28 |
Old World Delicatessen
|
Beverages
|
1869
|
29 |
Old World Delicatessen
|
Condiments
|
672.787506103516
|
30 |
Old World Delicatessen
|
Confections
|
3765.875
|
31 |
Old World Delicatessen
|
Dairy Products
|
802.5
|
32 |
Old World Delicatessen
|
Grains/Cereals
|
2146
|
33 |
Old World Delicatessen
|
Produce
|
848
|
34 |
Old World Delicatessen
|
Seafood
|
397.5
|
35 |
Rattlesnake Canyon Grocery
|
Beverages
|
18359.7500190735
|
36 |
Rattlesnake Canyon Grocery
|
Condiments
|
1340
|
37 |
Rattlesnake Canyon Grocery
|
Confections
|
6913.91292190552
|
38 |
Rattlesnake Canyon Grocery
|
Dairy Products
|
5294.86999511719
|
39 |
Rattlesnake Canyon Grocery
|
Grains/Cereals
|
4162.50500488281
|
40 |
Rattlesnake Canyon Grocery
|
Meat/Poultry
|
2178.39996337891
|
41 |
Rattlesnake Canyon Grocery
|
Produce
|
1851.05249977112
|
42 |
Rattlesnake Canyon Grocery
|
Seafood
|
521.530006408691
|
43 |
Save-a-lot Markets
|
Beverages
|
8458.20002746582
|
44 |
Save-a-lot Markets
|
Condiments
|
5486.20007324219
|
45 |
Save-a-lot Markets
|
Confections
|
10285.9050292969
|
46 |
Save-a-lot Markets
|
Dairy Products
|
19291.1000061035
|
47 |
Save-a-lot Markets
|
Grains/Cereals
|
8298.10000610352
|
48 |
Save-a-lot Markets
|
Meat/Poultry
|
25585.579788208
|
49 |
Save-a-lot Markets
|
Produce
|
3302
|
50 |
Save-a-lot Markets
|
Seafood
|
13316.6000061035
|
51 |
Split Rail Beer & Ale
|
Beverages
|
360
|
52 |
Split Rail Beer & Ale
|
Condiments
|
439
|
53 |
Split Rail Beer & Ale
|
Confections
|
309
|
54 |
Split Rail Beer & Ale
|
Dairy Products
|
576
|
55 |
Split Rail Beer & Ale
|
Meat/Poultry
|
236
|
56 |
Split Rail Beer & Ale
|
Produce
|
318
|
57 |
Split Rail Beer & Ale
|
Seafood
|
1354
|
58 |
The Big Cheese
|
Beverages
|
2775
|
59 |
The Big Cheese
|
Condiments
|
85.4000015258789
|
60 |
The Big Cheese
|
Dairy Products
|
69.5999984741211
|
61 |
The Big Cheese
|
Seafood
|
95
|
62 |
The Cracker Box
|
Beverages
|
114
|
63 |
The Cracker Box
|
Condiments
|
194.5
|
64 |
The Cracker Box
|
Grains/Cereals
|
70
|
65 |
The Cracker Box
|
Meat/Poultry
|
742.739990234375
|
66 |
The Cracker Box
|
Produce
|
456
|
67 |
The Cracker Box
|
Seafood
|
370
|
68 |
Trail's Head Gourmet Provisioners
|
Beverages
|
425
|
69 |
Trail's Head Gourmet Provisioners
|
Condiments
|
234
|
70 |
Trail's Head Gourmet Provisioners
|
Confections
|
640.899993896484
|
71 |
Trail's Head Gourmet Provisioners
|
Dairy Products
|
35
|
72 |
Trail's Head Gourmet Provisioners
|
Grains/Cereals
|
199.5
|
73 |
Trail's Head Gourmet Provisioners
|
Seafood
|
36.7999992370606
|
74 |
White Clover Markets
|
Beverages
|
8884.69998168945
|
75 |
White Clover Markets
|
Condiments
|
1878.12999916077
|
76 |
White Clover Markets
|
Confections
|
3714.12502288818
|
77 |
White Clover Markets
|
Dairy Products
|
2655.5
|
78 |
White Clover Markets
|
Grains/Cereals
|
577.600006103516
|
79 |
White Clover Markets
|
Meat/Poultry
|
3707.95001220703
|
80 |
White Clover Markets
|
Produce
|
182.400009155273
|
81 |
White Clover Markets
|
Seafood
|
2825
|
7. Complex Sales Report with Forced Order, Specific Joins, and Recompilation
SQL Server Query 2
-- Advanced Query: Complex Sales Report with Forced Order, Specific Joins, and Recompilation
SELECT
C.CompanyName,
E.FirstName + ' ' + E.LastName AS EmployeeName,
O.OrderDate,
SUM(OD.Quantity * OD.UnitPrice) AS OrderLineTotal
FROM Customers AS C -- First table in order
INNER HASH JOIN Orders AS O ON C.CustomerID = O.CustomerID -- Force HASH join for C-O
INNER LOOP JOIN Employees AS E ON O.EmployeeID = E.EmployeeID -- Force LOOP join for O-E
INNER HASH JOIN [Order Details] AS OD ON O.OrderID = OD.OrderID -- Force HASH join for O-OD
WHERE C.Region = 'WA'
AND O.OrderDate >= '1997-01-01'
GROUP BY C.CompanyName, E.FirstName, E.LastName, O.OrderDate
ORDER BY C.CompanyName, O.OrderDate
OPTION (FORCE ORDER, RECOMPILE); -- Force overall order and recompilation
Create SQL query with SqlQueryBuilder 2
var (sql7, parameters7) = new SqlQueryBuilder()
.Select()
.Column("C.CompanyName")
.Column(new CONCAT(new Column("E.FirstName"), " ", new Column("E.LastName")), "EmployeeName")
.Column("O.OrderDate")
.Column(new SUM(new ColumnArithmatic("OD.Quantity").MULTIPLY("OD.UnitPrice")), "OrderLineTotal")
.From("Customers", "C")
.Join(new List<IJoin>()
{
new INNERHASHJOIN().TableName("Orders","O")
.On(new Column("C.CustomerID").Equale(new Column("O.CustomerID"))),
new INNERLOOPJOIN().TableName("Employees", "E")
.On(new Column("O.EmployeeID").Equale(new Column("E.EmployeeID"))),
new INNERHASHJOIN().TableName("[Order Details]","OD")
.On(new Column("O.OrderID").Equale(new Column("OD.OrderID")))
})
.Where(new Where(new Column("C.Region").Equale("WA"))
.AND(new Column("O.OrderDate").GreaterThanOrEqualeTo("1997-01-01")))
.GroupBy(new GroupBy("C.CompanyName", "E.FirstName", "E.LastName", "O.OrderDate"))
.OrderBy(new OrderBy().SetColumnAscending("C.CompanyName")
.SetColumnAscending("O.OrderDate"))
.Option(new List<IOption>() { new FORCE_ORDER(), new RECOMPILE() })
.Build();
Query build by SqlQueryBuilder 2
SELECT C.CompanyName,
CONCAT(E.FirstName, @pMAIN_2507192011455355530, E.LastName) AS EmployeeName,
O.OrderDate,
SUM(OD.Quantity * OD.UnitPrice) AS OrderLineTotal
FROM Customers AS C
INNER HASH JOIN
Orders AS O
ON C.CustomerID = O.CustomerID
INNER LOOP JOIN
Employees AS E
ON O.EmployeeID = E.EmployeeID
INNER HASH JOIN
[Order Details] AS OD
ON O.OrderID = OD.OrderID
WHERE C.Region = @pMAIN_2507192011455355531
AND O.OrderDate >= @pMAIN_2507192011455355532
GROUP BY C.CompanyName, E.FirstName, E.LastName, O.OrderDate
ORDER BY C.CompanyName ASC, O.OrderDate ASC
OPTION (FORCE ORDER, RECOMPILE);
Parameters (If used)
Name |
Value |
@pMAIN_2507192011455355530 |
|
@pMAIN_2507192011455355531 |
WA |
@pMAIN_2507192011455355532 |
1997-01-01 |
Query Results 2:
|
CompanyName |
EmployeeName |
OrderDate |
OrderLineTotal |
1 |
Lazy K Kountry Store
|
Nancy Davolio
|
3/21/1997 12:00:00 AM
|
147.0000
|
2 |
Lazy K Kountry Store
|
Laura Callahan
|
5/22/1997 12:00:00 AM
|
210.0000
|
3 |
Trail's Head Gourmet Provisioners
|
Margaret Peacock
|
6/19/1997 12:00:00 AM
|
764.3000
|
4 |
Trail's Head Gourmet Provisioners
|
Anne Dodsworth
|
6/23/1997 12:00:00 AM
|
569.0000
|
5 |
Trail's Head Gourmet Provisioners
|
Michael Suyama
|
1/8/1998 12:00:00 AM
|
237.9000
|
6 |
White Clover Markets
|
Nancy Davolio
|
3/10/1997 12:00:00 AM
|
1125.5000
|
7 |
White Clover Markets
|
Robert King
|
3/24/1997 12:00:00 AM
|
704.0000
|
8 |
White Clover Markets
|
Margaret Peacock
|
4/11/1997 12:00:00 AM
|
1388.5000
|
9 |
White Clover Markets
|
Laura Callahan
|
7/11/1997 12:00:00 AM
|
1476.1000
|
10 |
White Clover Markets
|
Janet Leverling
|
10/6/1997 12:00:00 AM
|
2334.0000
|
11 |
White Clover Markets
|
Laura Callahan
|
10/8/1997 12:00:00 AM
|
996.0000
|
12 |
White Clover Markets
|
Janet Leverling
|
10/30/1997 12:00:00 AM
|
468.4500
|
13 |
White Clover Markets
|
Margaret Peacock
|
11/13/1997 12:00:00 AM
|
1770.0000
|
14 |
White Clover Markets
|
Margaret Peacock
|
1/30/1998 12:00:00 AM
|
3523.4000
|
15 |
White Clover Markets
|
Janet Leverling
|
2/24/1998 12:00:00 AM
|
1924.2500
|
16 |
White Clover Markets
|
Andrew Fuller
|
4/17/1998 12:00:00 AM
|
8902.5000
|
17 |
White Clover Markets
|
Robert King
|
5/1/1998 12:00:00 AM
|
928.7500
|
8. Targeted Customer Order Analysis with LOOP JOINs
SQL Server Query 3
-- Advanced Query: Targeted Customer Order Analysis with LOOP JOINs
SELECT
C.CompanyName,
C.City,
O.OrderID,
O.OrderDate,
OD.ProductID,
OD.Quantity,
OD.UnitPrice,
OD.Discount
FROM Customers AS C WITH (INDEX(IX_Customers_Region)) -- Hint to use index for region filter
INNER LOOP JOIN Orders AS O ON C.CustomerID = O.CustomerID -- Force LOOP JOIN between Customers and Orders
INNER LOOP JOIN [Order Details] AS OD ON O.OrderID = OD.OrderID -- Force LOOP JOIN between Orders and Order Details
WHERE C.Region = 'WA' -- Assuming 'WA' yields a small number of customers
ORDER BY C.CompanyName, O.OrderDate, O.OrderID, OD.ProductID
OPTION (RECOMPILE); -- Optional: Force recompilation to ensure plan is fresh for this specific hint
Create SQL query with SqlQueryBuilder 3
var (sql8, parameters8) = new SqlQueryBuilder()
.Select()
.Columns("C.CompanyName","C.City","O.OrderID","O.OrderDate","OD.ProductID","OD.Quantity","OD.UnitPrice","OD.Discount")
.From("Customers", "C", new List<IHint>() { new INDEX().SetValues("IX_Customers_Region") })
.Join(new List<IJoin>()
{
new INNERLOOPJOIN().TableName("Orders", "O")
.On(new Column("C.CustomerID").Equale(new Column("O.CustomerID"))),
new INNERLOOPJOIN().TableName("[Order Details]","OD")
.On(new Column("O.OrderID").Equale(new Column("OD.OrderID")))
})
.Where(new Where(new Column("C.Region").Equale("WA")))
.OrderBy(new OrderBy().SetColumnAscending("C.CompanyName")
.SetColumnAscending("O.OrderDate")
.SetColumnAscending("O.OrderID")
.SetColumnAscending("OD.ProductID"))
.Option(new List<IOption>() { new RECOMPILE() })
.Build();
Query build by SqlQueryBuilder 3
SELECT C.CompanyName,
C.City,
O.OrderID,
O.OrderDate,
OD.ProductID,
OD.Quantity,
OD.UnitPrice,
OD.Discount
FROM Customers AS C WITH (INDEX (IX_Customers_Region))
INNER LOOP JOIN
Orders AS O
ON C.CustomerID = O.CustomerID
INNER LOOP JOIN
[Order Details] AS OD
ON O.OrderID = OD.OrderID
WHERE C.Region = @pMAIN_2507192011455577060
ORDER BY C.CompanyName ASC, O.OrderDate ASC, O.OrderID ASC, OD.ProductID ASC
OPTION (RECOMPILE);
Parameters (If used)
Name |
Value |
@pMAIN_2507192011455577060 |
WA |
Query Results 3:
|
CompanyName |
City |
OrderID |
OrderDate |
ProductID |
Quantity |
UnitPrice |
Discount |
1 |
Lazy K Kountry Store
|
Walla Walla
|
10482
|
3/21/1997 12:00:00 AM
|
40
|
10
|
14.7000
|
0
|
2 |
Lazy K Kountry Store
|
Walla Walla
|
10545
|
5/22/1997 12:00:00 AM
|
11
|
10
|
21.0000
|
0
|
3 |
Trail's Head Gourmet Provisioners
|
Kirkland
|
10574
|
6/19/1997 12:00:00 AM
|
33
|
14
|
2.5000
|
0
|
4 |
Trail's Head Gourmet Provisioners
|
Kirkland
|
10574
|
6/19/1997 12:00:00 AM
|
40
|
2
|
18.4000
|
0
|
5 |
Trail's Head Gourmet Provisioners
|
Kirkland
|
10574
|
6/19/1997 12:00:00 AM
|
62
|
10
|
49.3000
|
0
|
6 |
Trail's Head Gourmet Provisioners
|
Kirkland
|
10574
|
6/19/1997 12:00:00 AM
|
64
|
6
|
33.2500
|
0
|
7 |
Trail's Head Gourmet Provisioners
|
Kirkland
|
10577
|
6/23/1997 12:00:00 AM
|
39
|
10
|
18.0000
|
0
|
8 |
Trail's Head Gourmet Provisioners
|
Kirkland
|
10577
|
6/23/1997 12:00:00 AM
|
75
|
20
|
7.7500
|
0
|
9 |
Trail's Head Gourmet Provisioners
|
Kirkland
|
10577
|
6/23/1997 12:00:00 AM
|
77
|
18
|
13.0000
|
0
|
10 |
Trail's Head Gourmet Provisioners
|
Kirkland
|
10822
|
1/8/1998 12:00:00 AM
|
62
|
3
|
49.3000
|
0
|
11 |
Trail's Head Gourmet Provisioners
|
Kirkland
|
10822
|
1/8/1998 12:00:00 AM
|
70
|
6
|
15.0000
|
0
|
12 |
White Clover Markets
|
Seattle
|
10269
|
7/31/1996 12:00:00 AM
|
33
|
60
|
2.0000
|
0.05
|
13 |
White Clover Markets
|
Seattle
|
10269
|
7/31/1996 12:00:00 AM
|
72
|
20
|
27.8000
|
0.05
|
14 |
White Clover Markets
|
Seattle
|
10344
|
11/1/1996 12:00:00 AM
|
4
|
35
|
17.6000
|
0
|
15 |
White Clover Markets
|
Seattle
|
10344
|
11/1/1996 12:00:00 AM
|
8
|
70
|
32.0000
|
0.25
|
16 |
White Clover Markets
|
Seattle
|
10469
|
3/10/1997 12:00:00 AM
|
2
|
40
|
15.2000
|
0.15
|
17 |
White Clover Markets
|
Seattle
|
10469
|
3/10/1997 12:00:00 AM
|
16
|
35
|
13.9000
|
0.15
|
18 |
White Clover Markets
|
Seattle
|
10469
|
3/10/1997 12:00:00 AM
|
44
|
2
|
15.5000
|
0.15
|
19 |
White Clover Markets
|
Seattle
|
10483
|
3/24/1997 12:00:00 AM
|
34
|
35
|
11.2000
|
0.05
|
20 |
White Clover Markets
|
Seattle
|
10483
|
3/24/1997 12:00:00 AM
|
77
|
30
|
10.4000
|
0.05
|
21 |
White Clover Markets
|
Seattle
|
10504
|
4/11/1997 12:00:00 AM
|
2
|
12
|
19.0000
|
0
|
22 |
White Clover Markets
|
Seattle
|
10504
|
4/11/1997 12:00:00 AM
|
21
|
12
|
10.0000
|
0
|
23 |
White Clover Markets
|
Seattle
|
10504
|
4/11/1997 12:00:00 AM
|
53
|
10
|
32.8000
|
0
|
24 |
White Clover Markets
|
Seattle
|
10504
|
4/11/1997 12:00:00 AM
|
61
|
25
|
28.5000
|
0
|
25 |
White Clover Markets
|
Seattle
|
10596
|
7/11/1997 12:00:00 AM
|
56
|
5
|
38.0000
|
0.2
|
26 |
White Clover Markets
|
Seattle
|
10596
|
7/11/1997 12:00:00 AM
|
63
|
24
|
43.9000
|
0.2
|
27 |
White Clover Markets
|
Seattle
|
10596
|
7/11/1997 12:00:00 AM
|
75
|
30
|
7.7500
|
0.2
|
28 |
White Clover Markets
|
Seattle
|
10693
|
10/6/1997 12:00:00 AM
|
9
|
6
|
97.0000
|
0
|
29 |
White Clover Markets
|
Seattle
|
10693
|
10/6/1997 12:00:00 AM
|
54
|
60
|
7.4500
|
0.15
|
30 |
White Clover Markets
|
Seattle
|
10693
|
10/6/1997 12:00:00 AM
|
69
|
30
|
36.0000
|
0.15
|
31 |
White Clover Markets
|
Seattle
|
10693
|
10/6/1997 12:00:00 AM
|
73
|
15
|
15.0000
|
0.15
|
32 |
White Clover Markets
|
Seattle
|
10696
|
10/8/1997 12:00:00 AM
|
17
|
20
|
39.0000
|
0
|
33 |
White Clover Markets
|
Seattle
|
10696
|
10/8/1997 12:00:00 AM
|
46
|
18
|
12.0000
|
0
|
34 |
White Clover Markets
|
Seattle
|
10723
|
10/30/1997 12:00:00 AM
|
26
|
15
|
31.2300
|
0
|
35 |
White Clover Markets
|
Seattle
|
10740
|
11/13/1997 12:00:00 AM
|
28
|
5
|
45.6000
|
0.2
|
36 |
White Clover Markets
|
Seattle
|
10740
|
11/13/1997 12:00:00 AM
|
35
|
35
|
18.0000
|
0.2
|
37 |
White Clover Markets
|
Seattle
|
10740
|
11/13/1997 12:00:00 AM
|
45
|
40
|
9.5000
|
0.2
|
38 |
White Clover Markets
|
Seattle
|
10740
|
11/13/1997 12:00:00 AM
|
56
|
14
|
38.0000
|
0.2
|
39 |
White Clover Markets
|
Seattle
|
10861
|
1/30/1998 12:00:00 AM
|
17
|
42
|
39.0000
|
0
|
40 |
White Clover Markets
|
Seattle
|
10861
|
1/30/1998 12:00:00 AM
|
18
|
20
|
62.5000
|
0
|
41 |
White Clover Markets
|
Seattle
|
10861
|
1/30/1998 12:00:00 AM
|
21
|
40
|
10.0000
|
0
|
42 |
White Clover Markets
|
Seattle
|
10861
|
1/30/1998 12:00:00 AM
|
33
|
35
|
2.5000
|
0
|
43 |
White Clover Markets
|
Seattle
|
10861
|
1/30/1998 12:00:00 AM
|
62
|
3
|
49.3000
|
0
|
44 |
White Clover Markets
|
Seattle
|
10904
|
2/24/1998 12:00:00 AM
|
58
|
15
|
13.2500
|
0
|
45 |
White Clover Markets
|
Seattle
|
10904
|
2/24/1998 12:00:00 AM
|
62
|
35
|
49.3000
|
0
|
46 |
White Clover Markets
|
Seattle
|
11032
|
4/17/1998 12:00:00 AM
|
36
|
35
|
19.0000
|
0
|
47 |
White Clover Markets
|
Seattle
|
11032
|
4/17/1998 12:00:00 AM
|
38
|
25
|
263.5000
|
0
|
48 |
White Clover Markets
|
Seattle
|
11032
|
4/17/1998 12:00:00 AM
|
59
|
30
|
55.0000
|
0
|
49 |
White Clover Markets
|
Seattle
|
11066
|
5/1/1998 12:00:00 AM
|
16
|
3
|
17.4500
|
0
|
50 |
White Clover Markets
|
Seattle
|
11066
|
5/1/1998 12:00:00 AM
|
19
|
42
|
9.2000
|
0
|
51 |
White Clover Markets
|
Seattle
|
11066
|
5/1/1998 12:00:00 AM
|
34
|
35
|
14.0000
|
0
|
9. Advanced Query: Employee-Customer Sales Aggregation with HASH GROUP Hint
SQL Server Query 4
-- Advanced Query: Employee-Customer Sales Aggregation with HASH GROUP Hint
SELECT TOP 50
E.FirstName + ' ' + E.LastName AS EmployeeName,
C.CompanyName,
SUM(OD.Quantity * OD.UnitPrice * (1 - OD.Discount)) AS TotalSalesValue,
COUNT(DISTINCT O.OrderID) AS NumberOfOrders
FROM Employees AS E
JOIN Orders AS O ON E.EmployeeID = O.EmployeeID
JOIN Customers AS C ON O.CustomerID = C.CustomerID
JOIN [Order Details] AS OD ON O.OrderID = OD.OrderID
-- Adding a broad WHERE clause to simulate large input for aggregation, if needed
-- WHERE O.OrderDate >= '1996-01-01'
GROUP BY E.FirstName, E.LastName, C.CompanyName
ORDER BY EmployeeName, CompanyName -- Keep ORDER BY, but HASH GROUP might still be chosen before final sort
OPTION (HASH GROUP); -- Explicitly hint the optimizer to prefer Hash Aggregate
Create SQL query with SqlQueryBuilder 4
var (sql9, parameters9) = new SqlQueryBuilder()
.Select().Top(50)
.Column(new CONCAT(new Column("E.FirstName"), " ", new Column("E.LastName")), "EmployeeName")
.Column("C.CompanyName")
.Column(new SUM(new ColumnArithmatic("OD.Quantity").MULTIPLY("OD.UnitPrice")
.MULTIPLY().StartBracket(1).SUBTRACT("OD.Discount").EndBracket()), "TotalSalesValue")
.Column(new COUNT(new Column("O.OrderID"), true), "NumberOfOrders")
.From("Employees","E")
.Join(new List<IJoin>()
{
new INNERJOIN().TableName("Orders", "O")
.On(new Column("E.EmployeeID").Equale(new Column("O.EmployeeID"))),
new INNERJOIN().TableName("Customers", "C")
.On(new Column("O.CustomerID").Equale(new Column("C.CustomerID"))),
new INNERJOIN().TableName("[Order Details]", "OD")
.On(new Column("O.OrderID").Equale(new Column("OD.OrderID")))
})
.GroupBy(new GroupBy("E.FirstName", "E.LastName", "C.CompanyName"))
.OrderBy(new OrderBy().SetColumnAscending("EmployeeName")
.SetColumnAscending("CompanyName"))
.Option(new List<IOption>() { new HASH_GROUP() })
.Build();
Query build by SqlQueryBuilder 4
SELECT TOP 50 CONCAT(E.FirstName, @pMAIN_2507192011455705200, E.LastName) AS EmployeeName,
C.CompanyName,
SUM(OD.Quantity * OD.UnitPrice * (@pMAIN_2507192011455705201 - OD.Discount)) AS TotalSalesValue,
COUNT(DISTINCT O.OrderID) AS NumberOfOrders
FROM Employees AS E
INNER JOIN
Orders AS O
ON E.EmployeeID = O.EmployeeID
INNER JOIN
Customers AS C
ON O.CustomerID = C.CustomerID
INNER JOIN
[Order Details] AS OD
ON O.OrderID = OD.OrderID
GROUP BY E.FirstName, E.LastName, C.CompanyName
ORDER BY EmployeeName ASC, CompanyName ASC
OPTION (MERGE JOIN);
Parameters (If used)
Name |
Value |
@pMAIN_2507192011455705200 |
|
@pMAIN_2507192011455705201 |
1 |
Query Results 4:
|
EmployeeName |
CompanyName |
TotalSalesValue |
NumberOfOrders |
1 |
Andrew Fuller
|
Berglunds snabbköp
|
613.20000076294
|
1
|
2 |
Andrew Fuller
|
Blondesddsl père et fils
|
1176
|
1
|
3 |
Andrew Fuller
|
Bon app'
|
1930.39996337891
|
1
|
4 |
Andrew Fuller
|
Bottom-Dollar Markets
|
5436
|
2
|
5 |
Andrew Fuller
|
B's Beverages
|
1328
|
1
|
6 |
Andrew Fuller
|
Cactus Comidas para llevar
|
477
|
1
|
7 |
Andrew Fuller
|
Comércio Mineiro
|
405.75
|
1
|
8 |
Andrew Fuller
|
Consolidated Holdings
|
155.999997138977
|
1
|
9 |
Andrew Fuller
|
Die Wandernde Kuh
|
1614.80001831055
|
1
|
10 |
Andrew Fuller
|
Du monde entier
|
63
|
1
|
11 |
Andrew Fuller
|
Ernst Handel
|
10703.630065918
|
3
|
12 |
Andrew Fuller
|
Familia Arquibaldo
|
224.82999420166
|
1
|
13 |
Andrew Fuller
|
Folk och fä HB
|
7423.50004577637
|
3
|
14 |
Andrew Fuller
|
France restauration
|
1733.06005859375
|
1
|
15 |
Andrew Fuller
|
Franchi S.p.A.
|
315.799999237061
|
2
|
16 |
Andrew Fuller
|
Godos Cocina Típica
|
616.5
|
1
|
17 |
Andrew Fuller
|
Gourmet Lanchonetes
|
1498.35000610352
|
1
|
18 |
Andrew Fuller
|
Hanari Carnes
|
1946.51992797852
|
1
|
19 |
Andrew Fuller
|
HILARION-Abastos
|
880.5
|
1
|
20 |
Andrew Fuller
|
Hungry Owl All-Night Grocers
|
10604.9797973633
|
3
|
21 |
Andrew Fuller
|
Island Trading
|
446.599998474121
|
1
|
22 |
Andrew Fuller
|
Königlich Essen
|
3744
|
2
|
23 |
Andrew Fuller
|
La corne d'abondance
|
649
|
1
|
24 |
Andrew Fuller
|
La maison d'Asie
|
3097.8700170517
|
2
|
25 |
Andrew Fuller
|
Laughing Bacchus Wine Cellars
|
244.5
|
2
|
26 |
Andrew Fuller
|
Lehmanns Marktstand
|
1629.97500610352
|
1
|
27 |
Andrew Fuller
|
LILA-Supermercado
|
720
|
1
|
28 |
Andrew Fuller
|
LINO-Delicateses
|
1365.97999572754
|
2
|
29 |
Andrew Fuller
|
Lonesome Pine Restaurant
|
424
|
1
|
30 |
Andrew Fuller
|
Magazzini Alimentari Riuniti
|
2836.74996948242
|
3
|
31 |
Andrew Fuller
|
Mère Paillarde
|
3354
|
1
|
32 |
Andrew Fuller
|
Morgenstern Gesundkost
|
1200.79998779297
|
1
|
33 |
Andrew Fuller
|
North/South
|
252
|
1
|
34 |
Andrew Fuller
|
Old World Delicatessen
|
1411
|
1
|
35 |
Andrew Fuller
|
Ottilies Käseladen
|
1826.40002441406
|
2
|
36 |
Andrew Fuller
|
Pericles Comidas clásicas
|
1116.30000305176
|
2
|
37 |
Andrew Fuller
|
Piccolo und mehr
|
5899.45001220703
|
3
|
38 |
Andrew Fuller
|
Que Delícia
|
2216.87996292114
|
2
|
39 |
Andrew Fuller
|
Queen Cozinha
|
889.700004577637
|
1
|
40 |
Andrew Fuller
|
QUICK-Stop
|
42700.8001556396
|
6
|
41 |
Andrew Fuller
|
Rattlesnake Canyon Grocery
|
903.75
|
1
|
42 |
Andrew Fuller
|
Reggiani Caseifici
|
2269.5
|
2
|
43 |
Andrew Fuller
|
Ricardo Adocicados
|
2803
|
2
|
44 |
Andrew Fuller
|
Romero y tomillo
|
361
|
1
|
45 |
Andrew Fuller
|
Santé Gourmet
|
622.350006103516
|
1
|
46 |
Andrew Fuller
|
Save-a-lot Markets
|
7638.0998840332
|
4
|
47 |
Andrew Fuller
|
Seven Seas Imports
|
1228.80000305176
|
1
|
48 |
Andrew Fuller
|
Simons bistro
|
1405.20001220703
|
2
|
49 |
Andrew Fuller
|
Spécialités du monde
|
52.3499984741211
|
1
|
50 |
Andrew Fuller
|
Suprêmes délices
|
2866.5
|
2
|