# Neo4j: Conditional WHERE clause with APOC

Sometimes we want to be able to vary our Cypher queries based on the value of a parameter. I came across such a situation today, and thought I’d share how I solved it using the APOC library.

Let’s first setup some sample data:

``````UNWIND range(0, 5) AS id
CREATE (:Person {name: "person-" + id})``````

Now, if we want to get all pairs of people, we could write the following query:

``````MATCH (p1:Person), (p2:Person)
WHERE id(p1) < id(p2)
RETURN p1.name, p2.name``````

If we run that query we’ll see the following output:

Table 1. Results
p1.name p2.name

person-0

person-1

person-0

person-2

person-0

person-3

person-0

person-4

person-0

person-5

person-1

person-2

person-1

person-3

person-1

person-4

person-1

person-5

person-2

person-3

person-2

person-4

person-2

person-5

person-3

person-4

person-3

person-5

person-4

person-5

But we also want to search for a Person, based on a query parameter, and return the pairs from that Person to everybody else. Let’s see how to do that.

We’ll first create a parameter to find a subset of people:

``:param personSubstring => "person-3"``

And then the following query returns pairs from those people to everybody else:

``````MATCH (p1:Person), (p2:Person)
WHERE p1.name CONTAINS \$personSubstring AND p2 <> p1
RETURN p1.name, p2.name``````

If we run that query we’ll see the following output:

Table 2. Results
p1.name p2.name

person-3

person-0

person-3

person-1

person-3

person-2

person-3

person-4

person-3

person-5

What if we want to combine those queries? If `personSubstring` contains a value we’ll use that, and if not we’ll return all pairs of people.

We can use the APOC Library's `apoc.when` procedure to solve this problem. This procedure has the following parameters:

• `condition` - a statement that must return a boolean value

• `ifQuery` - the query to execute if the condition is true

• `elseQuery` - the query to execute if the condition is false

• `params` - parameters to pass to the queries

And we can call it like this:

``````CALL apoc.when(
\$personSubstring = '',
'MATCH (p1:Person), (p2:Person) WHERE id(p1) < id(p2) RETURN p1, p2',
'MATCH (p1:Person), (p2:Person) WHERE p1.name CONTAINS \$personSubstring AND p2 <> p1 RETURN p1, p2',
{personSubstring: \$personSubstring})
YIELD value
RETURN value.p1.name, value.p2.name``````

And now we can handle both use cases in one Cypher query.