Общие табличные выражения
- Простые
- Рекурсивные
Общие табличные выражения реализованы в 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