Adding sample for shortest path

Added a sample for shortest path. This is a new feature introduced in SQL Server 2019 CTP3.1
This commit is contained in:
shkale-msft
2019-06-26 01:13:27 -07:00
parent b9253c617f
commit 2298bc586b
4 changed files with 192 additions and 0 deletions
Binary file not shown.

After

Width:  |  Height:  |  Size: 62 KiB

@@ -0,0 +1,67 @@
# SHORTEST_PATH
SQL Server (starting with SQL Server 2017) and Azure SQL Database now let you create a graph database, to hold your entities and complex many to many relationships. There are several examples on github which demonstrate how the new graph features work. This example shows how you can use SHORTEST_PATH function to write a shortest path or arbitrary length traversal query. This feature is available for public preview with SQL Server 2019 CTP3.1
To demonstrate the functionality, we will be using AdventureWorks2014 as our sample database.
## Contents
[About this sample](#about-this-sample)<br/>
[Before you begin](#before-you-begin)<br/>
[Run this sample](#run-this-sample)<br/>
[Related links](#related-links)
## About this sample
1. **Applies to:**
- SQL Server 2019 CTP3.1 (or higher)
2. **Demos:**
- Build and populate graph node and edge tables
- Use SHORTEST_PATH function to compute shortest path
- between 2 given nodes.
- starting from a given node to all other nodes in the graph.
- starting from a given node to all other nodes, which are 1 to 3 hops away from the start node.
3. **Workload:** Queries executed on [AdventureWorks2014](https://github.com/Microsoft/sql-server-samples/releases/download/adventureworks/AdventureWorks2014.bak)
4. **Programming Language:** T-SQL
5. **Author:** Shreya Verma
## Before you begin
To run these demo scripts, you need the following prerequisites.
**Account and Software prerequisites:**
1. SQL Server 2019 CTP3.1 (or higher)
2. SQL Server Management Studio 18.x (or higher)
## Run This Sample
### Setup
#### SQL Server Setup
1. Download [**AdventureWorks2014.bak**](https://github.com/Microsoft/sql-server-samples/releases/download/adventureworks/AdventureWorks2014.bak)
2. Launch SQL Server Management Studio, connect to your SQL Server instance (2019) and restore **AdventureWorks2014.bak**. This document describes how to [Restore a Database Backup Using SSMS](https://docs.microsoft.com/en-us/sql/relational-databases/backup-restore/restore-a-database-backup-using-ssms).
#### Running the Sample Scripts
1. Once the database is restored, run the *setup-BOMGraph.sql* script to create the necessary graph node and edge tables. We will be using these tables to run our sample queries. The setup file creates Product node table and IsPartOf edge table, which represents the BOM for products in AdventureWorks Cycles manufacturing pipeline.
![AdventureWorksBOM](AdventureWorksBOM.png)
2. Run the *ShortestPath.sql* script to run some SHORTEST_PATH queries. The script has following example queries:
1. Starting from a given node, find shortest path to all the other nodes in the graph.
2. Starting from a given node, find shortest path to all the other nodes in the graph, which are 1 -3 hops away from the start node.
3. Find shortest path between 2 given nodes (start and end node)
## Related Links
For more information about Graph DB in SQL Server 2017, see these articles:
1. [Graph processing with SQL Server and Azure SQL Database](https://docs.microsoft.com/en-us/sql/relational-databases/graphs/sql-graph-overview)
2. [SQL Graph Architecture](https://docs.microsoft.com/en-us/sql/relational-databases/graphs/sql-graph-architecture)
3. [Using MATCH in MERGE DML](https://blogs.msdn.microsoft.com/sqlserverstorageengine/2018/07/16/match-support-in-merge-dml-for-graph-tables/)
4. [Edge Constraints on graph tables](https://blogs.msdn.microsoft.com/sqlserverstorageengine/2018/09/28/public-preview-of-graph-edge-constraints-on-sql-server-2019/)
@@ -0,0 +1,72 @@
USE AdventureWorks2014
GO
------------------------------------------------------------------------------------
-- Find all assemblies that require a Bearing Ball in the bill of materials
-- Or, Starting with a given node, find shortest paths to all the others nodes in
-- the graph
------------------------------------------------------------------------------------
SELECT
P1.ProductID,
P1.Name,
STRING_AGG(P2.Name,'->') WITHIN GROUP (GRAPH PATH) AS [Assembly],
LAST_VALUE(P2.ProductID) WITHIN GROUP (GRAPH PATH) AS [Final ProductID]
FROM
PRODUCT P1,
PRODUCT FOR PATH P2,
ISPARTOF FOR PATH IPO
WHERE
MATCH(SHORTEST_PATH(P1(-(IPO)->P2)+))
AND P1.ProductID = 2
ORDER BY P1.ProductID
------------------------------------------------------------------------------------
-- Find all products which are up to 3 levels away from Bearing Ball in BOM hierarchy
-- Or, find shortest path from a given start node to all other nodes in the graph,
-- which are 1-3 hops away from the start node.
------------------------------------------------------------------------------------
SELECT
P1.ProductID,
P1.Name,
STRING_AGG(P2.Name,'->') WITHIN GROUP (GRAPH PATH) AS [Assembly],
LAST_VALUE(P2.ProductID) WITHIN GROUP (GRAPH PATH) AS [Final ProductID],
COUNT(P2.ProductID) WITHIN GROUP (GRAPH PATH) AS Levels
FROM
PRODUCT P1,
PRODUCT FOR PATH P2,
ISPARTOF FOR PATH IPO
WHERE
MATCH(SHORTEST_PATH(P1(-(IPO)->P2){1,3}))
AND P1.ProductID = 2
ORDER BY P1.ProductID
------------------------------------------------------------------------------------
-- Find shortest path between 2 given nodes (start node and end node)
-- Note that, to apply filter on the end node, we have to use a subquery
-- but the filter applied on end node in outer query is pushed down while
-- computing the shortest path.
------------------------------------------------------------------------------------
SELECT
ProductID, Name, [Assembly], FinalProductID, Levels
FROM (
SELECT
P1.ProductID,
P1.Name,
STRING_AGG(P2.Name,'->') WITHIN GROUP (GRAPH PATH) AS [Assembly],
LAST_VALUE(P2.ProductID) WITHIN GROUP (GRAPH PATH) AS FinalProductID,
COUNT(P2.ProductID) WITHIN GROUP (GRAPH PATH) AS Levels
FROM
PRODUCT P1,
PRODUCT FOR PATH P2,
ISPARTOF FOR PATH IPO
WHERE
MATCH(SHORTEST_PATH(P1(-(IPO)->P2)+))
AND P1.ProductID = 2
) AS Q
WHERE Q.FinalProductID = 768
@@ -0,0 +1,53 @@
USE AdventureWorks2014
GO
-- create product node
CREATE TABLE dbo.Product (
ProductID INT,
Name NVARCHAR(50),
ProductNumber NVARCHAR(25),
StandardCost money,
ListPrice money,
DaysToManu INT,
Weight decimal(8,2),
SellStartDate datetime,
SellEndDate datetime,
) AS NODE;
GO
-- populate data into product node from Production.Product table
INSERT INTO dbo.Product
SELECT
p.ProductID,
p.Name,
p.ProductNumber,
p.StandardCost,
p.ListPrice,
p.Weight,
p.DaysToManufacture,
p.SellStartDate,
p.SellEndDate
FROM Production.Product p;
GO
-- create IsPartOf edge
CREATE TABLE IsPartOf (PerAssemblyQty decimal(8,2)) AS EDGE;
go
-- Insert into isPartOf edge BOM hierarchy links
INSERT INTO IsPartOf
(
$from_id,
$to_id,
PerAssemblyQty
)
SELECT
P.$node_id,
PP.$node_id,
BOM.PerAssemblyQty
FROM
dbo.Product AS P
JOIN
Production.BillOfMaterials AS BOM ON P.ProductId = BOM.ComponentID
JOIN
dbo.Product AS PP ON PP.ProductID = BOM.ProductAssemblyID