Чи є в Oracle еквівалент MySQL еквіваленту WH?
Чи є в Oracle еквівалент MySQL еквіваленту WH?
Відповіді:
Немає. Якщо (поки) хтось не розвине його (MySQL є відкритим кодом, кожен може зробити свій внесок.)
WITH
Ключове слово ANSI / ISO SQL використовується для визначення загальних табличних виразів (CTE) і спрощує складні запити з однією або декількома вкладеними посиланнями. Він доступний в Oracle, Postgres, SQL-Server, DB2, але не в MySQL.
Остаточний запит може містити посилання (як правило, у FROM
пункті, але вони можуть бути в будь-якій іншій частині) на будь-який із загальних виразів таблиці, один чи більше разів. Запит може бути записаний (без CTE) в MySQL за допомогою похідних таблиць, але посилання повинні робитися повторно.
Приклад нерозумного запиту, який показує всіх осіб, народжених у 50-х роках та в липні, та кількість усіх осіб, народжених у тому ж році:
WITH a AS
( SELECT name, birthdate, YEAR(birthdate) AS birthyear
FROM persons
WHERE birthdate >= '1950-01-01' AND birthdate < '1960-01-01'
)
, b AS
( SELECT birthyear, COUNT(*) AS cnt
FROM a
GROUP BY birthyear
)
SELECT a.name, a.birthdate, b.cnt AS number_of_births
FROM a JOIN b
ON a.birthyear = b.birthyear
WHERE MONTH(a.birthdate) = 7 ;
У MySQL це можна записати так:
SELECT a.name, a.birthdate, b.cnt AS number_of_births
FROM
( SELECT name, birthdate, YEAR(birthdate) AS birthyear
FROM persons
WHERE birthdate >= '1950-01-01' AND birthdate < '1960-01-01'
) AS a
JOIN
( SELECT birthyear, COUNT(*) AS cnt
FROM
( SELECT name, birthdate, YEAR(birthdate) AS birthyear
FROM persons
WHERE birthdate >= '1950-01-01' AND birthdate < '1960-01-01'
) AS aa
GROUP BY birthyear
) AS b
ON a.birthyear = b.birthyear
WHERE MONTH(a.birthdate) = 7 ;
Зауважте дублювання коду для похідної таблиці a
. У більш складних запитах код потрібно було б писати кілька разів.
Це спрацює, але шкода, що він не надасть переваги використання пункту WITH, тобто не виконувати один і той же запит кілька разів (складні запити можуть бути реально повільними і дуже вимогливими до двигуна бази даних; я зазнав цього) .
Я б запропонував вставити кожен пункт SELECT, визначений у вихідному пункті, до своєї тимчасової таблиці та використовувати їх всередині запиту . У MySQL тимчасова таблиця опуститься після закінчення сеансу роботи користувача.
Редагувати:
Я щойно побачив цю відповідь у подібній темі, яка чітко розкриває 3 обхідні варіанти MySQL :
/programming//a/1382618/2906290
і приклад процедури MySQL, яка створює та скидає тимчасові таблиці, якщо ви продовжуєте сеанс і хочете звільнити ці ресурси (я б використовував це лише як приклад синтаксису): /programming//a/ 5553145/2906290