# DELETE
{bdg-primary-line}`GQL clause`
Removes vertices and edges from the graph. `DETACH DELETE` removes a vertex's
edges along with it.
## Synopsis
[ DETACH ] DELETE expression [, expression ] ...
bold keywords · italic placeholders you supply · [ ] optional · ... repeatable. See Syntax conventions.
## Description
`DELETE` removes the graph elements its expressions evaluate to. It needs them
bound first, so it always follows a clause that found them.
- A **plain `DELETE` refuses a vertex that still has edges**. Deleting it would
leave edges pointing at nothing, so the clause raises an error and the
transaction rolls back.
- **`DETACH DELETE`** deletes the vertex's edges first and then the vertex. Use
it whenever the vertex might be connected.
- Deleting an **edge** never needs `DETACH`, and never touches its endpoints.
- Several expressions may be listed. They are deleted in the order given, so
listing an edge before its endpoints works without `DETACH`.
- `DELETE` runs once per incoming row. An element already deleted by an earlier
row is not an error.
- Each expression must be a vertex, an edge or a path. A property reference is
not accepted: to remove a property, use [`REMOVE`](remove.md).
- `DELETE` may end a query. Add a [`RETURN`](return.md) to see what went.
## Parameters
DETACH
: Delete each vertex's connected edges along with it.
expression
: An expression yielding a vertex, an edge or a path, usually a variable bound
by a [`MATCH`](match.md).
## Examples
Every example runs against [the example dataset](../../get_started/example-dataset.md).
The first example builds the subgraph the rest remove, so the dataset ends as it
began.
### Build something to delete
```cypher
CREATE (:movie {title: 'Tenet', year: 2020, genre: 'Action'});
MATCH (d:person {name: 'Christopher Nolan'}), (m:movie {title: 'Tenet'})
CREATE (d)-[:directed]->(m);
MATCH (m:movie {title: 'Tenet'})
CREATE (a:person {name: 'Elizabeth Debicki', born: 1990})-[:acted_in {role: 'Kat'}]->(m);
```
```
UPDATE 1
UPDATE 1
UPDATE 2
```
`Tenet` now has two edges:
```cypher
MATCH (m:movie {title: 'Tenet'})-[r]-(x)
RETURN label(r) AS edge, count(*) AS n
ORDER BY edge;
```
```
edge | n
------------+---
"acted_in" | 1
"directed" | 1
(2 rows)
```
### See a plain DELETE refuse a connected vertex
```cypher
MATCH (m:movie {title: 'Tenet'}) DELETE m;
```
```
ERROR: Vertex with connected edges cannot be removed
HINT: Use DETACH DELETE or remove connected edges before deleting the vertex.
```
Nothing is deleted. The graph never holds an edge whose endpoint is gone.
### Delete an edge
An edge needs no `DETACH`, and its endpoints survive:
```cypher
MATCH (:person {name: 'Elizabeth Debicki'})-[r:acted_in]->(:movie {title: 'Tenet'})
DELETE r;
```
```
UPDATE 1
```
```cypher
MATCH (p:person {name: 'Elizabeth Debicki'})-[r]-() RETURN count(*) AS edges;
```
```
edges
-------
0
(1 row)
```
### Delete an unconnected vertex, and see what went
With no edges left, a plain `DELETE` succeeds. A `RETURN` after it reports the
element that was removed:
```cypher
MATCH (p:person {name: 'Elizabeth Debicki'})
DELETE p
RETURN properties(p) AS removed;
```
```
removed
---------------------------------------------
{"born": 1990, "name": "Elizabeth Debicki"}
(1 row)
```
### Delete a vertex and its edges together
`Tenet` still has the `directed` edge. `DETACH DELETE` takes both:
```cypher
MATCH (m:movie {title: 'Tenet'}) DETACH DELETE m;
```
```
UPDATE 2
```
Two elements: the edge and the vertex. Christopher Nolan is untouched, and keeps
his other edges:
```cypher
MATCH (p:person {name: 'Christopher Nolan'})-[:directed]->(m:movie)
RETURN m.title AS film
ORDER BY film;
```
```
film
----------------
"Inception"
"Interstellar"
(2 rows)
```
### Delete several elements in one clause
List the edge before the vertices it joins and no `DETACH` is needed, because by
the time the vertices are deleted the edge is gone:
```cypher
CREATE (:person {name: 'Extra Two'});
MATCH (a:person {name: 'Extra Two'}) CREATE (a)-[:acted_in]->(:movie {title: 'Scratch'});
```
```
UPDATE 1
UPDATE 2
```
```cypher
MATCH (a:person {name: 'Extra Two'})-[r:acted_in]->(m:movie {title: 'Scratch'})
DELETE r, a, m;
```
```
UPDATE 3
```
The dataset is back to its original size:
```cypher
MATCH (n) RETURN label(n) AS label, count(*) AS n ORDER BY label;
```
```
label | n
----------+----
"movie" | 18
"person" | 28
(2 rows)
```
## Notes
`DELETE` takes elements, not properties. Naming a property is refused rather than
quietly ignored:
```cypher
MATCH (m:movie {title: 'The Matrix'}) DELETE m.title;
```
```
ERROR: node, relationship, or path is expected
LINE 1: MATCH (m:movie {title: 'The Matrix'}) DELETE m.title;
^
```
Use [`REMOVE`](remove.md) for a property, or `SET m.title = NULL`.
```{note}
`DETACH DELETE` on a busy vertex can delete a great many edges in one statement,
and all of it is one transaction. Count first — `MATCH (v)-[r]-() RETURN count(r)`
— when you are not sure how large the blast radius is.
```
## Compatibility
### NODETACH (ISO/IEC 39075 §13.5)
The standard's `` is `[ DETACH | NODETACH ] DELETE`, with
`NODETACH` the implicit default. AgensGraph implements the default but not the
keyword: `NODETACH DELETE m` is a syntax error. Write a plain `DELETE`, which
means the same thing.
## See also
- [`REMOVE`](remove.md) — remove properties instead of elements
- [`MATCH`](match.md) — binding the elements to delete
- [`CREATE`](create.md), [`MERGE`](merge.md) — the clauses that put them there
- [Data definition](../ddl/index) — dropping a whole label or graph