Общие табличные выражения
- Простые
- Рекурсивные
Общие табличные выражения реализованы в DaJet Script согласно стандарту SQL. Более подробную справку по их использованию можно посмотреть в соответствующей документации, как по Microsoft SQL Server, так и по PostgreSQL. Единственным отличием синтаксиса языка запросов DaJet Script от стандарта SQL является замена ключевого слова WITH, которое используется для определения общих табличных выражений, на выражение CREATE COMPUTED TABLE.
Простой пример использования общего табличного выражения
DECLARE @table array
DECLARE @СрезОстатков datetime = '2023-04-01T00:00:00';
USE 'mssql://server/database'
CREATE COMPUTED TABLE Остатки AS
(
SELECT Период, Номенклатура
, Сумма = SUM(CASE WHEN ВидДвижения = 0 THEN Сумма ELSE -Сумма END)
FROM РегистрНакопления.РегистрНакопленияОстатки
WHERE Период < @СрезОстатков
GROUP BY Период, Номенклатура
HAVING SUM(CASE WHEN ВидДвижения = 0 THEN Сумма ELSE -Сумма END) > 0
)
SELECT Период, Товар = Товар.Наименование, Сумма
INTO @table
FROM Остатки
INNER JOIN Справочник.Номенклатура AS Товар
ON Остатки.Номенклатура = Товар.Ссылка
END
RETURN @table
Ссылка одного общего табличного выражения на предыдущее
DECLARE @table array
DECLARE @ДатаСреза datetime = '2024-08-01T00:00:00';
USE 'mssql://server/database'
CREATE COMPUTED TABLE СрезПоследних AS
(
SELECT Валюта, Период = MAX(Период)
FROM РегистрСведений.КурсыВалют
WHERE Период < @ДатаСреза
GROUP BY Валюта
),
КурсыВалютНаДату AS
(
SELECT СрезПоследних.Период AS ДатаКурса,
КурсыВалют.Валюта,
КурсыВалют.Курс,
КурсыВалют.Кратность
FROM СрезПоследних
INNER JOIN РегистрСведений.КурсыВалют AS КурсыВалют
ON КурсыВалют.Период = СрезПоследних.Период
AND КурсыВалют.Валюта = СрезПоследних.Валюта
)
SELECT Валюта = Валюта.Наименование
, ДатаКурса, Курс, Кратность
INTO @table
FROM КурсыВалютНаДату AS Курсы
INNER JOIN Справочник.Валюты AS Валюта
ON Курсы.Валюта = Валюта.Ссылка
END
RETURN @table
Простой пример генерации последовательности чисел
DECLARE @table array
USE 'mssql://server/database'
CREATE COMPUTED TABLE РекурсивныйЗапрос AS
(
SELECT 1 AS Уровень
UNION ALL
SELECT parent.Уровень + 1
FROM РекурсивныйЗапрос AS parent
WHERE parent.Уровень + 1 < 5
)
SELECT Уровень INTO @table
FROM РекурсивныйЗапрос
ORDER BY Уровень DESC
END
RETURN @table
Иерархия: ссылка общего табличного выражения на само себя
DECLARE @table array
DECLARE @КодГруппы string = 'PG-11';
USE 'pgsql://postgres:postgres@localhost:5432/database'
CREATE COMPUTED TABLE РекурсивныйЗапрос AS
(
SELECT 0 AS Уровень, Ссылка
, КодРодителя = Код
, КодТовара = Код
, Наименование, ЭтоГруппа
FROM Справочник.Номенклатура
WHERE Код = @КодГруппы
UNION ALL
SELECT Предыдущий.Уровень + 1, Ссылка
, КодРодителя = Предыдущий.КодТовара
, КодТовара = Текущий.Код
, Текущий.Наименование
, Текущий.ЭтоГруппа
FROM Справочник.Номенклатура AS Текущий
INNER JOIN РекурсивныйЗапрос AS Предыдущий
ON Предыдущий.Ссылка = Текущий.Родитель
)
SELECT Уровень
, Родитель = КодРодителя
, Код = КодТовара
, Наименование
, ЭтоГруппа = CASE WHEN ЭтоГруппа = FALSE
THEN 'да' ELSE 'нет'
END
INTO @table
FROM РекурсивныйЗапрос
ORDER BY Уровень, ЭтоГруппа DESC;
END
RETURN @table