Временные таблицы SQL используются для того, чтобы хранить временные данные. Они создаются на непродолжительный период времени, а именно на время сеанса или транзакции базы данных. Как правило, они используются для хранения промежуточных результатов, которые были получены в результате обработки сложных запросов или вычислений. Помимо этого, их можно использовать для упрощения многоэтапных запросов. Кроме того, мы можем выполнять с временными таблицами CRUD-операции (create, read, update, delete – создание, чтение, обновление, удаление) и операции соединения – все как с обычными таблицами. Временные таблицы удаляются автоматически при завершении сеанса, или их может явным образом удалить пользователь.
Временные таблицы поддерживаются разными базами данных, например, MySQL, Oracle и SQL Server. Однако в зависимости от того, какой сервер баз данных вы используете, функции и синтаксис могут отличаться. В этой статье мы будем использовать SQL Server. В нем существуют два вида временных таблиц:
- Локальные временные таблицы
- Глобальные временные таблицы
Локальные временные таблицы
Локальные временные таблицы создаются с помощью оператора CREATE TABLE, за которым следует название таблицы с одним символом «решетка» (#) перед ним. Они доступны только в рамках текущего сеанса пользователя и автоматически удаляются после того, как сеанс, в котором они были созданы, завершится. Вот пример создания локальной временной таблицы:
CREATE TABLE #TempTable (ID INT, Name VARCHAR(50));
Этот оператор создает локальную временную таблицу #TempTable, у которой есть два столбца: ID и Name. Столбец ID имеет тип INT, а столбец Name - тип VARCHAR с ограничением в 50 символов. Для добавления данных в локальную временную таблицу мы можем использовать обычные операторы вставки. Вот пример:
INSERT INTO #TempTable (ID, Name) VALUES (1, 'Educative'), (2, 'DevPath');
Обратите внимание на то, что в приведенном выше примере мы создали временную таблицу с помощью оператора CREATE, а затем добавили в нее данные с помощью оператора INSERT.
После того, как мы создали временную таблицу и добавили в нее данные, мы можем использовать эти данные в запросах подобно тому, как мы бы то делали с обычной таблицей. Например, для того, чтобы получить данные из временной таблицы, мы можем воспользоваться оператором SELECT:
SELECT * FROM #TempTable;
Ниже вы можете видеть вывод команд, приведенных выше:
Пример выше демонстрирует то, что из себя представляет временная таблица в SQL. Также существует еще один способ создания временной таблицы и добавления в нее данных – оператор INTO. Для того, чтобы разобраться, как он работает, давайте представим, что у нас есть таблица Sales со следующими столбцами: SaleID, ProductID, SalesAmount, SaleDate, и выглядит она следующим образом:
SaleID (PK) |
ProductID |
SalesAmount |
SaleDate |
1 |
1 |
1000 |
19-06-2023 |
2 |
1 |
500 |
21-06-2023 |
3 |
2 |
300 |
22-06-2023 |
4 |
2 |
200 |
23-06-2023 |
5 |
1 |
700 |
23-06-2023 |
… |
… |
… |
… |
Допустим, что в рамках этого примера мы хотим создать временную таблицу, используя таблицу Sales, но выбрав при этом только столбцы ProductID и SalesAmount. Следующий синтаксис – это второй способ создания временной таблицы и добавления в нее данных (с помощью оператора INTO):
SELECT ProductID, SalesAmount INTO #TempTable FROM Sales
В примере выше мы создаем временную таблицу #TempTable, у которой есть два столбца: ProductID и SalesAmount. Эти столбцы определяются выборочным списком оператора SELECT. Запрос, который приведен выше, создает временную таблицу и добавляет в нее данные из таблицы Sales.
Для того, чтобы удалить локальную временную таблицу, вам понадобиться следующий синтаксис:
DROP TABLE #TempTable;
Пример
В этом примере мы создадим локальную временную таблицу, в которой будет храниться общий объем продаж продукции. Для этого создадим временную таблицу с двумя столбцами. Первый столбец – это ID продукции, а второй – объем продаж для этой продукции. Давайте для начала создадим временную таблицу:
CREATE TABLE #TempResults (ProductID INT, TotalSales DECIMAL(10, 2));
После того, как мы создали временную таблицу, мы можем сделать запрос и заполнить ее. В данном случае мы предполагаем, что в базе данных имеется таблица с именем Sales, в которой содержится информация о продукции и объемах ее продаж. Ниже приведен пример таблицы Sales, а также запросы для ее создания и заполнения:
Таблица Sales
SaleID (PK) |
ProductID |
SalesAmount |
SaleDate |
1 |
1 |
1000 |
19-06-2023 |
2 |
1 |
500 |
21-06-2023 |
3 |
2 |
300 |
22-06-2023 |
4 |
2 |
200 |
23-06-2023 |
5 |
1 |
700 |
23-06-2023 |
… |
… |
… |
… |
Запросы
CREATE TABLE [dbo].[Sales]( [SaleID] [int] PRIMARY KEY,[ProductID] [int] ,[SalesAmount] [decimal](18, 0) ,[SaleDate] [date] , ); |
INSERT [Sales] ([SaleID], [ProductID], [SalesAmount], [SaleDate]) VALUES (1, 1, 1000 , '2023-06-19' ) |
INSERT [Sales] ([SaleID], [ProductID], [SalesAmount], [SaleDate]) VALUES (2, 1, 500 , '2023-06-21' ) |
INSERT [Sales] ([SaleID], [ProductID], [SalesAmount], [SaleDate]) VALUES (3, 2, 300 , '2023-06-22' ) |
INSERT [Sales] ([SaleID], [ProductID], [SalesAmount], [SaleDate]) VALUES (4, 2, 200 , '2023-06-23' ) |
INSERT [Sales] ([SaleID], [ProductID], [SalesAmount], [SaleDate]) VALUES (5, 1, 700 , '2023-06-23' ) |
Следующий запрос – это запрос для добавления данных из таблицы Sales во временную таблицу:
INSERT INTO #TempResults (ProductID, TotalSales)
SELECT ProductID, SUM(SalesAmount)
FROM Sales
GROUP BY ProductID;
После того, как мы добавили данные во временную таблицу, мы можем использовать ее для дальнейших вычислений и запросов. Например, для того, чтобы получить список продукции, объем продаж которой превышает 1000, мы можем сделать следующий запрос:
SELECT ProductID, TotalSales
FROM #TempResults
WHERE TotalSales > 1000;
Результат будет следующий:
Пример, приведенный выше, демонстрирует то, как можно использовать временную таблицу для хранения промежуточных результатов. В следующем разделе мы рассмотрим, что такое глобальные временные таблицы.
Глобальные временные таблицы
Глобальные временные таблицы создаются с помощью оператора CREATE TABLE, после которого идет имя таблицы с двойным символом «решетка» (##) перед ним. Они доступны для всех пользователей сеанса в рамках данной базы данных и удаляются после завершения последнего сеанса, который ее использует. Вот пример создания глобальной базы данных:
CREATE TABLE ##TempTable (ID INT, Name VARCHAR(50));
Этот оператор создает глобальную временную таблицу #TempTable, у которой есть два столбца: ID и Name. Столбец ID имеет тип INT, а столбец Name - тип VARCHAR с ограничением в 50 символов. Для добавления данных в локальную временную таблицу мы можем использовать обычные операторы вставки. Вот пример:
INSERT INTO ##TempTable (ID, Name) VALUES (1, 'Educative'), (2, 'DevPath');
После того, как мы создали временную таблицу и добавили в нее данные, мы можем использовать эти данные в запросах подобно тому, как мы бы то делали с обычной таблицей. Например, для того, чтобы получить данные из временной таблицы, мы можем воспользоваться оператором SELECT:
SELECT * FROM ##TempTable;
Для того, чтобы удалить глобальную временную таблицу, вам понадобиться следующий синтаксис:
DROP TABLE ##TempTable;
Принцип использования глобальной временной таблицы аналогичен принципу использования локальной. Однако есть небольшие различия, которые представлены в следующей таблице:
Локальная временная таблица |
Глобальная временная таблица |
Доступна для текущего сеанса |
Доступна для всех сеансов |
Начинается с одного символа «решетка» |
Начинается с двойного символа «решетка» |
Существует до завершения сеанса |
Существует до тех пор, пока не будут завершены все связанные с ней сеансы |
Недоступна для других сеансов |
Доступна для всех сессий в рамках одной базы данных |
Чаще всего используется для промежуточных результатов и вычислений |
Подходит для обмена временными данными между сеансами |
В заключение следует отметить, что временные таблицы полезны при работе с большими объемами данных и сложными запросами. Они помогают хранить промежуточные данные в рамках определенного сеанса или транзакции базы данных.