Возврат CTE (общий столовый экспрессин) - PullRequest
0 голосов
/ 08 июля 2019

Я задавал вопрос раньше, но я настолько запутал запрос, что не смог взять решение и применить его к исходному запросу. Поэтому я пробую это снова.

У меня есть CTE, который мне нужно вернуть в «нормальный» запрос для MySQL 5.6. Мы не будем обновлять MySQL 8 или MariaDB 10.x в ближайшее время для этого проекта.

Запрос выглядит следующим образом:

        WITH currentUserPermissions (permissionID, action, level) AS (
            SELECT
                p.permissionID,
                p.action,
                CASE WHEN p.level = 1 AND rp.level = 1 THEN 2 ELSE COALESCE(rp.level, 0) END AS level
            FROM user_org_sport op
                JOIN rolePermissions rp ON op.roleID = rp.roleID AND op.orgID = rp.orgID
                JOIN permissions p ON p.permissionID = rp.permissionID
            WHERE op.userProfileID = :userID
                AND op.orgID = :orgID
                AND p.systemFlag = 0
        )

        SELECT action, level
        FROM currentUserPermissions

        UNION

        SELECT p.action, p.level
        FROM permissions p
        WHERE p.systemFlag = -1

        UNION

        SELECT p.action, 0 AS level
        FROM permissions p
            LEFT JOIN currentUserPermissions cup ON cup.action = p.action
        WHERE cup.action IS NULL
            AND p.systemFlag = 0

Я не специалист по базе данных (эксперт по предметной области), поэтому любая помощь будет принята. Из-за отсутствия опыта работы с базой данных я не смог применить предыдущий ответ к своему запросу.

1 Ответ

2 голосов
/ 08 июля 2019

Вам нужно будет скопировать CTE один раз для каждой ссылки на него:

SELECT action, level
FROM (
    SELECT
        p.permissionID,
        p.action,
        CASE WHEN p.level = 1 AND rp.level = 1 THEN 2 ELSE COALESCE(rp.level, 0) END AS level
    FROM user_org_sport op
    JOIN rolePermissions rp ON op.roleID = rp.roleID AND op.orgID = rp.orgID
    JOIN permissions p ON p.permissionID = rp.permissionID
    WHERE op.userProfileID = :userID
      AND op.orgID = :orgID
      AND p.systemFlag = 0
) x

UNION

SELECT p.action, p.level
FROM permissions p
WHERE p.systemFlag = -1

UNION

SELECT p.action, 0 AS level
FROM permissions p
LEFT JOIN (
    SELECT
        p.permissionID,
        p.action,
        CASE WHEN p.level = 1 AND rp.level = 1 THEN 2 ELSE COALESCE(rp.level, 0) END AS level
    FROM user_org_sport op
    JOIN rolePermissions rp ON op.roleID = rp.roleID AND op.orgID = rp.orgID
    JOIN permissions p ON p.permissionID = rp.permissionID
    WHERE op.userProfileID = :userID
      AND op.orgID = :orgID
      AND p.systemFlag = 0
) cup ON cup.action = p.action
WHERE cup.action IS NULL
  AND p.systemFlag = 0

Конечно, MySQL 5.x добавляет избыточность вашему запросу, а также становится медленнее, поскольку CTE может потребоваться вычислять дважды, а не один раз.

...