Comparing Cypher with SQL
While there are key differences between Cypher® and SQL, it is still possible to compare both languages and write equivalent SQL statements using Cypher. The Northwind dataset is used here to better illustrate the comparison.
|
For a more in-depth explanation on the differences and similarities between graph and relational databases, see Transition from relational to graph database. |
Indexing
Indexes are available both in SQL and Cypher. They make searching for a specific node label and attribute combination more efficient.
Indexes in Cypher are only used for finding the starting points of a query; all subsequent pattern matching is done through the graph structure. Cypher supports range, text, point, lookup, full-text, and vector indexes.
In the Northwind dataset, adding indexes on productName and unitPrice makes searching for a product and its price quicker:
| SQL | Cypher |
|---|---|
|
|
Query examples
Select and return records
| SQL | Cypher |
|---|---|
To select and return records in SQL, select everything from the
|
In Cypher, you
|
Field access, ordering, and paging
Rather than returning all attributes, you can filter out the ones you are interested in — ProductName and UnitPrice, for example.
| SQL | Cypher |
|---|---|
In SQL, this is how you order items by price and return the 10 most expensive items:
|
The statement is similar in Cypher, except for the pattern matching part:
|
| p.productName | p.unitPrice |
|---|---|
"Côte de Blaye" |
263.5 |
"Thüringer Rostbratwurst" |
123.79 |
"Mishi Kobe Niku" |
97.0 |
"Sir Rodney’s Marmalade" |
81.0 |
"Carnarvon Tigers" |
62.5 |
"Raclette Courdavault" |
55.0 |
"Manjimup Dried Apples" |
53.0 |
"Tarte au sucre" |
49.3 |
"Ipoh Coffee" |
46.0 |
"Rössle Sauerkraut" |
45.6 |
|
Remember that labels, relationship types, and property names are case sensitive in Neo4j. For more details on naming rules, see the Cypher Manual → Naming rules and recommendations. |
Find a single product by name
There are different ways to query the database and retrieve a single item, for example, a product named Chocolade.
You can do that, for example, by filtering by equality:
| SQL | Cypher |
|---|---|
In SQL, you can filter data using the
|
In Cypher, the
A shorter option is to use the label
|
| p.productName | p.unitPrice |
|---|---|
"Chocolade" |
12.75 |
Filter products
Filter by list/range
| SQL | Cypher |
|---|---|
In SQL, you can use the operator
|
Cypher has full collection support, including
|
| p.productName | p.unitPrice |
|---|---|
"Chocolade" |
12.75 |
"Chai" |
18.0 |
Filter by multiple numeric and textual predicates
| SQL | Cypher |
|---|---|
This query retrieves products with a name starting with "C" and a price larger than 100:
|
In Cypher, the
You can also use a regular expression to get all products with name starting with "C" and their prices:
|
| p.productName | p.unitPrice |
|---|---|
"Côte de Blaye" |
263.5 |
Joining products with customers
| SQL | Cypher |
|---|---|
In SQL, if you want to see who bought
|
In Cypher, there is no need to
|
| c.companyName |
|---|
"Victuailles en stock" |
"Ernst Handel" |
"Antonio Moreno Taquería" |
"Furia Bacalhau e Frutos do Mar" |
"Around the Horn" |
"Queen Cozinha" |
Total spent in each product
By summing up product prices and ordered quantities, an aggregated view per product for the customer is provided.
You can use aggregation functions like sum, count, avg, and max in both SQL and Cypher.
| SQL | Cypher |
|---|---|
If you want to see what a company (e.g. Drachenblut Delikatessen) paid in total per product, including where they had no orders for products, you have to use
|
In Cypher, you need to turn the
Then you
|
| p.productName | totalPrice |
|---|---|
"Gumbär Gummibärchen" |
372 |
"Perth Pasties" |
640 |
"Konbu" |
114 |
"Jack’s New England Clam Chowder" |
81 |
"Queso Cabrales" |
420 |
"Raclette Courdavault" |
1650 |
"Lakkalikööri" |
168 |
"Rhönbräu Klosterbier" |
72 |
"Gorgonzola Telino" |
200 |
Amount of products supplied
The previous example mentioned aggregation and used the SUM function to find out how much a company has spent when purchasing specific products.
You can use the COUNT function in Cypher to also count how many products are offered by a supplier, for example.
| SQL | Cypher | ||
|---|---|---|---|
In SQL, aggregation is explicit, so you have to provide all grouping keys again in the
|
In Cypher, grouping for aggregation is implicit. As soon as you use the first aggregation function, all non-aggregated columns automatically become grouping keys:
|
| Supplier | NumberOfProducts |
|---|---|
"Pavlova" |
5 |
"Plutzer Lebensmittelgroßmärkte AG" |
5 |
"Specialty Biscuits" |
4 |
"New Orleans Cajun Delights" |
4 |
"Grandma Kelly’s Homestead" |
3 |
List of products supplied
In Cypher you can use the COLLECT function to gather all nodes connected to others, but SQL doesn’t have a direct equivalent to it.
| SQL | Cypher | ||
|---|---|---|---|
In SQL, if you want a lit of what products the suppliers offer, you use
|
In Cypher, you can either return the structure like in SQL or use the
|
| Supplier | ProductsSupplied |
|---|---|
"Aux joyeux ecclésiastiques" |
["Côte de Blaye", "Chartreuse verte"] |
"Bigfoot Breweries" |
["Sasquatch Ale", "Laughing Lumberjack Lager", "Steeleye Stout"] |
"Cooperativa de Quesos 'Las Cabras'" |
["Queso Manchego La Pastora", "Queso Cabrales"] |
"Escargots Nouveaux" |
["Escargots de Bourgogne"] |
"Exotic Liquids" |
["Aniseed Syrup", "Chang", "Chai"] |