Общие табличные выражения

Общие табличные выражения в языке запросов DaJet реализованы аналогично стандарту SQL. Исключением является только синтаксис, который был изменён в целях его унификации относительно синтаксиса создания временных таблиц.

Главное отличие общих табличных выражений от временных таблиц заключается в том, что они "вычисляются" в момент обращения к ним из тела запроса SQL. В этом смысле их использование аналогично использованию представлений (view), объявленных в тексте запроса (inline view).

Общие табличные выражения могут ссылаться друг на друга и на самих себя. В последнем случае (ссылка на саму себя) реализуется механизм рекурсивного запроса.

Общие табличные выражения DaJet могут использоваться совместно с командами SELECT, INSERT, UPDATE и UPSERT, играя роль источника данных для основной команды. Использование в составе команды DELETE находится в разработке.

Пример использования общего табличного выражения:

DECLARE @ДатаОстатка datetime = '2014-12-31T23:59:59';

CREATE COMPUTED TABLE Остатки AS -- Общее табличное выражение
(
  SELECT Период, Номенклатура,
         SUM(CASE WHEN ВидДвижения = 0 -- Приход
                  THEN  ВНаличии
                  ELSE -ВНаличии END) AS Сумма
    FROM РегистрНакопления.ТоварыНаСкладах
   WHERE Период <= @ДатаОстатка
   GROUP BY Период, Номенклатура
  HAVING SUM(CASE WHEN ВидДвижения = 0 -- Приход
                  THEN  ВНаличии
                  ELSE -ВНаличии END) >= 50
)
-- Тело основного запроса
    SELECT Период, Товар.Наименование, Сумма
      FROM Остатки
INNER JOIN Справочник.Номенклатура AS Товар
        ON Остатки.Номенклатура = Товар.Ссылка

Пример ссылки одного общего табличного выражения на другое:

DECLARE @ДатаСреза datetime = '2021-07-31T23:59:59';

CREATE COMPUTED TABLE СрезПоследних AS -- Общее табличное выражение
(
  SELECT Валюта, MAX(Период) AS Период
    FROM РегистрСведений.КурсыВалют
   WHERE Период <= @ДатаСреза
   GROUP BY Валюта
),
КурсыВалютНаДату AS -- Общее табличное выражение
(
      SELECT СрезПоследних.Период AS ДатаКурса,
             КурсыВалют.Валюта,
             КурсыВалют.Курс,
             КурсыВалют.Кратность
        FROM СрезПоследних
  INNER JOIN РегистрСведений.КурсыВалют AS КурсыВалют
          ON КурсыВалют.Период = СрезПоследних.Период
         AND КурсыВалют.Валюта = СрезПоследних.Валюта
)
-- Тело основного запроса
    SELECT ДатаКурса, Валюта.Наименование, Курс, Кратность
      FROM КурсыВалютНаДату  AS Курсы
INNER JOIN Справочник.Валюты AS Валюта
        ON Курсы.Валюта = Валюта.Ссылка

Пример рекурсивного общего табличного выражения:

DECLARE @КодГруппы string = 'MS-10';

CREATE COMPUTED TABLE РекурсивныйЗапрос AS
(
  SELECT 0 AS Уровень,         Код AS Группа,
         Ссылка, Наименование, Код AS Товар
    FROM Справочник.Номенклатура
   WHERE Код = @КодГруппы -- Корневая группа

   UNION ALL

   SELECT parent.Уровень + 1,        parent.Товар,
          Ссылка, child.Наименование, child.Код
     FROM Справочник.Номенклатура AS child
    INNER JOIN  РекурсивныйЗапрос AS parent
       ON parent.Ссылка = child.Родитель
)
SELECT Уровень, Группа, Товар, Наименование
  FROM РекурсивныйЗапрос
 ORDER BY Уровень, Группа, Товар

УровеньГруппаТоварНаименование
0MS-10MS-10MS-10
1MS-10MS-04Товар 04
1MS-10MS-11MS-11
2MS-11MS-05Товар 05
2MS-11MS-06Товар 06