Использование Cypher в CTE, операторах JOIN и SQL-выражениях

Использование Cypher в CTE

Использование Cypher внутри общего табличного выражения (CTE) не ограничено.

Запрос

WITH graph_query AS (
    SELECT *
        FROM cypher('graph_name', $$
        MATCH (n)
        RETURN n.name, n.age
    $$) AS (name agtype, age agtype)
)
SELECT * FROM graph_query;

Результат

name age
'Andres' 36
'Tobias' 25
'Peter' 35
3 строки возвращено

Использование Cypher в операторах JOIN

Запросы Cypher могут использоваться как источник данных в предложении JOIN.

Примечание!
Запросы Cypher, содержащие предложения CREATE, SET или REMOVE, нельзя использовать в SQL-запросах с JOIN. Такие операции нарушают работу системы транзакций PostgreSQL. В качестве обходного решения можно обернуть запрос Cypher в CTE. Подробнее см. раздел "Использование CTE с CREATE, REMOVE и SET".

Запрос

SELECT id,
    graph_query.name = t.name AS names_match,
    graph_query.age = t.age AS ages_match
FROM schema_name.sql_person AS t
JOIN cypher('graph_name', $$
        MATCH (n:Person)
        RETURN n.name, n.age, id(n)
$$) AS graph_query(name agtype, age agtype, id agtype)
ON t.person_id = graph_query.id;

Результат

id names_match ages_match
1 True True
2 False True
3 True False
3 строки возвращено

Использование Cypher в SQL-выражениях

Cypher нельзя использовать непосредственно внутри SQL-выражений — запрос Cypher должен находиться в предложении FROM. Однако при обёртке в подзапрос он ведёт себя как любой стандартный SQL-запрос.

Примечание!
В YMatrix AGE запрещено использовать запросы Cypher с предложениями CREATE, SET или REMOVE в SQL-операторах записи (INSERT, DELETE, UPDATE). Например:

INSERT INTO t  
SELECT * FROM cypher('graph_name', $$  
    CREATE (a)  
    RETURN a  
$$) AS (a agtype);  

Использование Cypher с оператором =

Если известно, что запрос Cypher возвращает ровно один столбец и одну строку, допустимо использовать оператор сравнения =.

SELECT t.name, t.age
FROM schema_name.sql_person AS t
WHERE t.name = (
    SELECT a
    FROM cypher('graph_name', $$
            MATCH (v)
            RETURN v.name
    $$) AS (name varchar(50))
    ORDER BY name
    LIMIT 1
);

Результат

name age
'Andres' 36
1 строка возвращена

Использование Cypher с оператором IN PostgreSQL

Если запрос Cypher возвращает один столбец и потенциально несколько строк, используйте оператор IN.

Запрос

SELECT t.name, t.age
FROM schema_name.sql_person AS t
WHERE t.name IN (
    SELECT *
    FROM cypher('graph_name', $$
        MATCH (v:Person)
        RETURN v.name
    $$) AS (a agtype)
);

Результат

name age
'Andres' 36
'Tobias' 25
'Peter' 35
3 строки возвращено

Использование Cypher с оператором EXISTS PostgreSQL

Если запрос Cypher может возвращать несколько столбцов и несколько строк, используйте оператор EXISTS.

Запрос

SELECT t.name, t.age
FROM schema_name.sql_person AS t
WHERE EXISTS (
    SELECT *
    FROM cypher('graph_name', $$
        MATCH (v:Person)
        RETURN v.name, v.age
    $$) AS (name agtype, age agtype)
    WHERE name = t.name AND age = t.age
);

Результат

name age
'Andres' 36
'Tobias' 25
2 строки возвращено

Запрос к нескольким графам

Одно SQL-выражение может одновременно запрашивать произвольное количество графов.

Запрос

SELECT graph_1.name, graph_1.age, graph_2.license_number
FROM cypher('graph_1', $$
    MATCH (v:Person)
    RETURN v.name, v.age
$$) AS graph_1(name agtype, age agtype)
JOIN cypher('graph_2', $$
    MATCH (v:Doctor)
    RETURN v.name, v.license_number
$$) AS graph_2(name agtype, license_number agtype)
ON graph_1.name = graph_2.name;

Результат

name age license_number
'Andres' 36 1234567890
1 строка возвращена