The challenge is to find the most efficient way to generate a row counter within groups. I’m going to test it against my database of customers 190,000 distinct customers with 180,000 distinct customer orders (old ones have been warehoused) having 240,000 order details from 2800 products. I’m fairly sure I’ve indexed my tables properly.
The recordset that I want to generate is the top 50 distinct customers who have the most number of distinct items ordered within a single order. I’ve created example data and tables to make this fairly easy to test your SQL against, but let’s change the 50 to just top 2 for simplicity.
Here are a few special considerations:
[ul][li]If the same customer has more than one order only select the order that contains the most number of DISTINCT items ordered.[/li]
[li]The top 2 refers to the Count(Items) per customer order not to the top 2 customers consequently the final listing can have more than two customers with the same Count(Items).[/li]
[li]Use temp tables if you like, but it would be interesting to compare single query solutions against all others.[/li][/ul]
I haven’t done it yet, but my intention is to write a cursor approach for comparison. With the example data, you should get these results:
[tt]
# PDesc OId CName
1 Apple Fritter 10 Chrissie1
2 Caramel Pecal Roll 10 Chrissie1
3 Chocolate Donut 10 Chrissie1
4 Custard Bismark 10 Chrissie1
1 Caramel Pecal Roll 12 ESQuared
2 Chocolate Donut 12 ESQuared
3 Custard Bismark 12 ESQuared
1 Apple Fritter 13 SQLSister
2 Caramel Pecal Roll 13 SQLSister
3 Custard Bismark 13 SQLSister
[/tt]
-Karl
[red] Cursors, triggers, user-defined functions and dynamic SQL are an axis of evil![/red]
[green]Life's uncertain...eat dessert first...www.deerfieldbakery.com[/green]
The recordset that I want to generate is the top 50 distinct customers who have the most number of distinct items ordered within a single order. I’ve created example data and tables to make this fairly easy to test your SQL against, but let’s change the 50 to just top 2 for simplicity.
Here are a few special considerations:
[ul][li]If the same customer has more than one order only select the order that contains the most number of DISTINCT items ordered.[/li]
[li]The top 2 refers to the Count(Items) per customer order not to the top 2 customers consequently the final listing can have more than two customers with the same Count(Items).[/li]
[li]Use temp tables if you like, but it would be interesting to compare single query solutions against all others.[/li][/ul]
I haven’t done it yet, but my intention is to write a cursor approach for comparison. With the example data, you should get these results:
[tt]
# PDesc OId CName
1 Apple Fritter 10 Chrissie1
2 Caramel Pecal Roll 10 Chrissie1
3 Chocolate Donut 10 Chrissie1
4 Custard Bismark 10 Chrissie1
1 Caramel Pecal Roll 12 ESQuared
2 Chocolate Donut 12 ESQuared
3 Custard Bismark 12 ESQuared
1 Apple Fritter 13 SQLSister
2 Caramel Pecal Roll 13 SQLSister
3 Custard Bismark 13 SQLSister
[/tt]
Code:
[green]/*
DROP TABLE KarlsCustomer
DROP TABLE KarlsOrder
DROP TABLE KarlsOrderDetail
DROP TABLE KarlsProduct
*/
[/green][Blue]CREATE[/Blue] [Blue]TABLE[/Blue] KarlsCustomer
[Gray]([/Gray]CId [Blue]int[/Blue] [Fuchsia]Identity[/Fuchsia] [Gray]([/Gray]1[Gray],[/Gray]1[Gray])[/Gray] [Blue]PRIMARY[/Blue] [Blue]KEY[/Blue][Gray],[/Gray]
CName [Blue]varchar[/Blue][Gray]([/Gray]10[Gray])[/Gray][Gray])[/Gray]
[Blue]CREATE[/Blue] [Blue]TABLE[/Blue] KarlsOrder
[Gray]([/Gray]OId [Blue]int[/Blue] [Blue]PRIMARY[/Blue] [Blue]KEY[/Blue][Gray],[/Gray]
CId [Blue]int[/Blue][Gray])[/Gray]
[Blue]CREATE[/Blue] [Blue]TABLE[/Blue] KarlsOrderDetail
[Gray]([/Gray]ODId [Blue]int[/Blue] [Blue]PRIMARY[/Blue] [Blue]KEY[/Blue][Gray],[/Gray]
OId [Blue]int[/Blue][Gray],[/Gray]
PId [Blue]int[/Blue][Gray])[/Gray]
[Blue]CREATE[/Blue] [Blue]TABLE[/Blue] KarlsProduct
[Gray]([/Gray]PId [Blue]int[/Blue] [Fuchsia]Identity[/Fuchsia] [Gray]([/Gray]1[Gray],[/Gray]1[Gray])[/Gray] [Blue]PRIMARY[/Blue] [Blue]KEY[/Blue][Gray],[/Gray]
PDesc [Blue]varchar[/Blue][Gray]([/Gray]20[Gray])[/Gray][Gray])[/Gray]
[Blue]INSERT[/Blue] [Blue]INTO[/Blue] KarlsCustomer
[Blue]SELECT[/Blue] [red]'SQLSister'[/red] [Blue]UNION[/Blue]
[Blue]SELECT[/Blue] [red]'vongrunt'[/red] [Blue]UNION[/Blue]
[Blue]SELECT[/Blue] [red]'ESQuared'[/red] [Blue]UNION[/Blue]
[Blue]SELECT[/Blue] [red]'Chrissie1'[/red]
[Blue]INSERT[/Blue] [Blue]INTO[/Blue] KarlsProduct
[Blue]SELECT[/Blue] [red]'Chocolate Donut'[/red] [Blue]UNION[/Blue]
[Blue]SELECT[/Blue] [red]'Apple Fritter'[/red] [Blue]UNION[/Blue]
[Blue]SELECT[/Blue] [red]'Caramel Pecal Roll'[/red] [Blue]UNION[/Blue]
[Blue]SELECT[/Blue] [red]'Custard Bismark'[/red]
[Blue]INSERT[/Blue] [Blue]INTO[/Blue] KarlsOrderDetail
[Blue]SELECT[/Blue] 101[Gray],[/Gray]10[Gray],[/Gray]1 [Blue]UNION[/Blue]
[Blue]SELECT[/Blue] 102[Gray],[/Gray]10[Gray],[/Gray]2 [Blue]UNION[/Blue]
[Blue]SELECT[/Blue] 103[Gray],[/Gray]10[Gray],[/Gray]3 [Blue]UNION[/Blue]
[Blue]SELECT[/Blue] 104[Gray],[/Gray]10[Gray],[/Gray]4 [Blue]UNION[/Blue]
[Blue]SELECT[/Blue] 105[Gray],[/Gray]11[Gray],[/Gray]1 [Blue]UNION[/Blue]
[Blue]SELECT[/Blue] 106[Gray],[/Gray]11[Gray],[/Gray]3 [Blue]UNION[/Blue]
[Blue]SELECT[/Blue] 107[Gray],[/Gray]11[Gray],[/Gray]4 [Blue]UNION[/Blue]
[Blue]SELECT[/Blue] 108[Gray],[/Gray]11[Gray],[/Gray]1 [Blue]UNION[/Blue]
[Blue]SELECT[/Blue] 109[Gray],[/Gray]11[Gray],[/Gray]3 [Blue]UNION[/Blue]
[Blue]SELECT[/Blue] 110[Gray],[/Gray]12[Gray],[/Gray]2 [Blue]UNION[/Blue]
[Blue]SELECT[/Blue] 111[Gray],[/Gray]12[Gray],[/Gray]3 [Blue]UNION[/Blue]
[Blue]SELECT[/Blue] 112[Gray],[/Gray]12[Gray],[/Gray]4 [Blue]UNION[/Blue]
[Blue]SELECT[/Blue] 113[Gray],[/Gray]13[Gray],[/Gray]1 [Blue]UNION[/Blue]
[Blue]SELECT[/Blue] 114[Gray],[/Gray]13[Gray],[/Gray]2 [Blue]UNION[/Blue]
[Blue]SELECT[/Blue] 115[Gray],[/Gray]13[Gray],[/Gray]4 [Blue]UNION[/Blue]
[Blue]SELECT[/Blue] 116[Gray],[/Gray]14[Gray],[/Gray]1 [Blue]UNION[/Blue]
[Blue]SELECT[/Blue] 117[Gray],[/Gray]14[Gray],[/Gray]2
[Blue]INSERT[/Blue] [Blue]INTO[/Blue] KarlsOrder
[Blue]SELECT[/Blue] 10[Gray],[/Gray] 1 [Blue]UNION[/Blue]
[Blue]SELECT[/Blue] 11[Gray],[/Gray] 1 [Blue]UNION[/Blue]
[Blue]SELECT[/Blue] 12[Gray],[/Gray] 2 [Blue]UNION[/Blue]
[Blue]SELECT[/Blue] 13[Gray],[/Gray] 3 [Blue]UNION[/Blue]
[Blue]SELECT[/Blue] 14[Gray],[/Gray] 4
[red] Cursors, triggers, user-defined functions and dynamic SQL are an axis of evil![/red]
[green]Life's uncertain...eat dessert first...www.deerfieldbakery.com[/green]