While sql цикл: MS SQL Server и T-SQL
Содержание
Цикл WHILE для выбора данных за период в T-SQL
Время прочтения: 4 мин.
Зачастую в нашей
работе возникает потребность получить набор данных за определенный период.
Сделать это можно несколькими способами. В этой статье рассмотрим применение
цикла WHILE для задачи
поиска расходных операций за несколько месяцев по перечню счетов и сравним его
с запросом, в котором весь период будет указан в блоке WHERE.
Для начала разберем синтаксис конструкции WHILE. Выглядит он следующим образом:
WHILE [логическое условие] BEGIN [инструкция] END
В блоке Условие находится выражение,
возвращающее значение TRUE или FALSE, в блоке Инструкций будет находиться наш запрос на
выбор необходимого набора данных. Блок инструкций необходимо «ограничить»
словами управления BEGIN и END.
Теперь рассмотрим на примере применение
цикла WHILE и сравним его с простым запросом. Для
начала создадим таблицы для перечня счетов (1000 счетов с движением средств),
результатов простого запроса и результатов цикла WHILE.
CREATE TABLE [TB44_SANDBOX].[mis].[depohist_test_accounts] ( [account_nbr] nvarchar(255) ) ON [PRIMARY] WITH (DATA_COMPRESSION = PAGE) GO CREATE TABLE [TB44_SANDBOX].[mis].[depohist_test_query] ( [DEPOHIST_ID_MAJOR] bigint ,[DEPOHIST_ID_MINOR] bigint ,[DEPOHIST_ID_MEGA] bigint ,[DEPOSIT_ID_MAJOR] bigint ,[DEPOSIT_ID_MINOR] bigint ,[DEPOSIT_ID_MEGA] bigint ,[PERSON_ID_MAJOR] bigint ,[PERSON_ID_MINOR] bigint ,[PERSON_ID_MEGA] bigint ) ON [PRIMARY] WITH (DATA_COMPRESSION = PAGE) GO CREATE TABLE [TB44_SANDBOX].[mis].[depohist_test_while] ( [DEPOHIST_ID_MAJOR] bigint ,[DEPOHIST_ID_MINOR] bigint ,[DEPOHIST_ID_MEGA] bigint ,[DEPOSIT_ID_MAJOR] bigint ,[DEPOSIT_ID_MINOR] bigint ,[DEPOSIT_ID_MEGA] bigint ,[PERSON_ID_MAJOR] bigint ,[PERSON_ID_MINOR] bigint ,[PERSON_ID_MEGA] bigint ) ON [PRIMARY] WITH (DATA_COMPRESSION = PAGE) GO
Информация об операциях в нашем случае хранится в [BACKOFFICE_STG].[DEPOSIT].[VW_DEPOHIST], где созданы индексы на номер счета ([DEPOSIT_PRINTABLENO]) и дату операции ([DEPOHIST_OpDay]). Далее напишем запрос на выборку и вставку данных с указанием всего периода в блоке WHERE.
INSERT INTO [TB44_SANDBOX].[mis].[depohist_test_query] SELECT [dh].[DEPOHIST_ID_MAJOR] ,[dh].[DEPOHIST_ID_MINOR] ,[dh].[DEPOHIST_ID_MEGA] ,[dh].[DEPOSIT_ID_MAJOR] ,[dh].[DEPOSIT_ID_MINOR] ,[dh].[DEPOSIT_ID_MEGA] ,[dh].[PERSON_ID_MAJOR] ,[dh].[PERSON_ID_MINOR] ,[dh].[PERSON_ID_MEGA] FROM [BACKOFFICE_STG].[DEPOSIT].[VW_DEPOHIST] AS [dh] WITH(NOLOCK) INNER JOIN [TB44_SANDBOX].[mis].[depohist_test_accounts] AS [t] WITH(NOLOCK) ON [dh].[DEPOSIT_PRINTABLENO] = [t].[account_nbr] WHERE [dh].[DEPOHIST_OpCash] < 0 AND [dh].[DEPOHIST_OpDay] >= '2020-01-01' AND [dh].[DEPOHIST_OpDay] < '2020-03-01'
Данный запрос выполнялся около полутора минут и вставил в таблицу 1606 строк.
Теперь напишем запрос с использованием цикла WHILE.
DECLARE @startdate date = '2020-01-01' DECLARE @enddate date = '2020-03-01' WHILE @startdate < @enddate BEGIN INSERT INTO [TB44_SANDBOX].[mis].[depohist_test_while] SELECT [dh].[DEPOHIST_ID_MAJOR] ,[dh].[DEPOHIST_ID_MINOR] ,[dh].[DEPOHIST_ID_MEGA] ,[dh].[DEPOSIT_ID_MAJOR] ,[dh].[DEPOSIT_ID_MINOR] ,[dh].[DEPOSIT_ID_MEGA] ,[dh].[PERSON_ID_MAJOR] ,[dh].[PERSON_ID_MINOR] ,[dh].[PERSON_ID_MEGA] FROM [BACKOFFICE_STG].[DEPOSIT].[VW_DEPOHIST] AS [dh] WITH(NOLOCK) INNER JOIN [TB44_SANDBOX].[mis].[depohist_test_accounts] AS [t] WITH(NOLOCK) ON [dh].[DEPOSIT_PRINTABLENO] = [t].[account_nbr] WHERE [dh].[DEPOHIST_OpCash] < 0 AND [dh].[DEPOHIST_OpDay] = @startdate SET @startdate = DATEADD(DAY, 1, @startdate) END
В начале определяем две переменные, в
которых будет находится необходимый период. Далее логическое условие выполнения
цикла – дата начала периода строго меньше даты окончания периода. В теле цикла
между словами управления BEGIN и END наш запрос на выборку и вставку данных. Обратите
внимание, что вместо периода для столбца [dh].[DEPOHIST_OpDay] мы
указываем конкретное значение, которое содержит переменная @startdate. После запроса мы присваиваем нашей
переменной новое значение в +1 день от текущего значения с помощью функции DATEADD(),
чтобы перейти на следующий шаг выполнения цикла.
Таким образом наш цикл будет выполняться
пока значение переменной @startdate не станет равным
значению @enddate, и на каждом шаге
цикла будет выполняться запрос на выборку данных за конкретную дату.
Теперь запустим этот запрос и сравним его
результаты с предыдущим.
На вкладке «Сообщения» будет несколько строк, которые соответствуют выполненному запросу на каждом шаге цикла. Запрос с использованием цикла выполнялся 35 секунд и вставил в таблицу те же 1606 строк.
Данный способ позволяет быстрее получить необходимые данные, так как при каждом выполнении будет использоваться индекс на дату, и, если в результате выполнения запроса случится какая-либо ошибка, сохранить результат ранее отработанных шагов цикла.
sql — Update через цикл While
Вопрос задан
Изменён
3 месяца назад
Просмотрен
947 раз
Подскажите пожалуйста:
Есть таблица t1 в ней есть поля допустим ID, FirstValue, SecondValue
ID FirstValue SecondValue 1 null 1.1 клиент 2 null Вася 3 null Петя 4 null 1.2 партнеры 5 null Газпром 6 null USA
нужно проитерировать чтоб получился такой результат,только не курсором а циклом:
ID FirstValue SecondValue 1 1.1 клиент 1.1 клиент 2 1.1 клиент Вася 3 1.1 клиент Петя 4 1.2 партнеры 1.2 партнеры 5 1.2 партнеры Газпром 6 1.2 партнеры USA
Подскажите как? можно на словах)
- sql
- sql-server
2
Разобрался спасибо!
set nocount on if isnull(object_id('tempdb..#t1'),0) <> 0 drop table #t1 create table #t1 ( ID int identity(1,1), FirstValue varchar(20), SecondValue varchar(20) ) insert into #t1 (FirstValue, SecondValue) select '', '1.1 Клиенты' union all select '', 'Клиент 1' union all select '', 'Клиент 2' union all select '', 'Клиент 3' union all select '', '1.2 Партнеры' union all select '', 'Партнер 1' union all select '', 'Партнер 2' union all select '', 'Партнер 3' begin tran declare @ID int, @SecondValue varchar(20) select @ID = 0, @SecondValue = '' while 1 = 1 begin select @ID = min(ID) from #t1 where ID > @ID if @ID is null break select @SecondValue = SecondValue from #t1 where ID = @ID if isnull(@SecondValue,'') <> '' begin update #t1 set FirstValue = ( select top 1 SecondValue from #t1 where ID <= @ID and SecondValue like '1.%' order by ID desc ) where ID = @ID end end rollback
Получается:
1
Зарегистрируйтесь или войдите
Регистрация через Google
Регистрация через Facebook
Регистрация через почту
Отправить без регистрации
Почта
Необходима, но никому не показывается
Отправить без регистрации
Почта
Необходима, но никому не показывается
Нажимая на кнопку «Отправить ответ», вы соглашаетесь с нашими пользовательским соглашением, политикой конфиденциальности и политикой о куки
SQL Server WHILE — Как создать цикл в SQL Server
Резюме : в этом руководстве вы узнаете, как использовать оператор SQL Server WHILE
для многократного выполнения блока операторов на основе указанного условия.
Обзор оператора
WHILE
Оператор WHILE
представляет собой оператор потока управления, который позволяет многократно выполнять блок операторов до тех пор, пока заданное условие TRUE
.
Ниже показан синтаксис оператора WHILE
:
WHILE Boolean_expression { sql_statement | блок_операторов} Язык кода: SQL (язык структурированных запросов) (sql)
В этом синтаксисе:
Во-первых, Boolean_expression
— это выражение, которое оценивается как TRUE
или FALSE
.
Второй, sql_statement | statement_block
— это любая инструкция Transact-SQL или набор инструкций Transact-SQL. Блок операторов определяется с помощью BEGIN...END
инструкция.
Если Boolean_expression
оценивается как FALSE
при входе в цикл, никакие операторы внутри цикла WHILE
выполняться не будут.
Внутри цикла WHILE
необходимо изменить некоторые переменные, чтобы Boolean_expression
возвращал FALSE
в некоторых точках. В противном случае у вас будет неопределенный цикл.
Обратите внимание, что если Boolean_expression
содержит Оператор SELECT
должен быть заключен в круглые скобки.
Чтобы немедленно выйти из текущей итерации цикла, используйте оператор BREAK
. Чтобы пропустить текущую итерацию цикла и запустить новую, используется оператор CONTINUE
.
SQL Server
WHILE
пример
Давайте рассмотрим пример использования оператора SQL Server WHILE
, чтобы лучше понять его.
В следующем примере показано, как использовать WHILE
инструкция для вывода чисел от 1 до 5:
DECLARE @counter INT = 1; ПОКА @counter <= 5 НАЧИНАТЬ ПЕЧАТЬ @счетчик; SET @счетчик = @счетчик + 1; КОНЕЦ Язык кода: SQL (язык структурированных запросов) (sql)
Вывод:
1 2 3 4 5
В этом примере:
- Сначала мы объявили переменную
@counter
и установили ее значение равным единице. - Затем в условии оператора
WHILE
мы проверили,0005 @counter меньше или равно пяти. Если это было не так, мы распечатывали@counter
и увеличивали его значение на единицу. После пяти итераций@counter
равен 6, что вызвало условиеWHILE
, оцениваемое какFALSE
, цикл остановился.
Чтобы узнать, как использовать цикл WHILE
для обработки построчно, ознакомьтесь с учебным пособием по курсору.
Из этого руководства вы узнали, как использовать SQL Server WHILE
оператор для повторения выполнения блока операторов на основе указанного условия.
SQL Server WHILE LOOP — javatpoint
следующий → В этой статье вы найдете полный обзор использования цикла WHILE в SQL Server. Цикл WHILE — это оператор потока управления, используемый для многократного выполнения набора операторов до тех пор, пока не будет выполнено заданное условие . Блок-схема цикла WHILEСледующая блок-схема объясняет полный рабочий процесс цикла WHILE в SQL Server: На этой диаграмме видно, что указанное условие проверяется для каждой итерации, и на основе результата оценки определяется поток кода. Если результат оценивается как TRUE, поток управления переходит внутрь цикла для дальнейшего выполнения. Если оцениваемый результат равен FALSE, поток управления выйдет из цикла, и будет выполнен любой оператор или запрос вне цикла. СинтаксисСледующий синтаксис иллюстрирует цикл WHILE в SQL Server: ПОКА логическое_условие В этом синтаксисе у нас есть следующие параметры или аргументы:
Пример цикла WHILE Давайте разберемся, как работает цикл WHILE в SQL Server, на примере. В данном примере мы сначала объявили значение целочисленного типа и установили его значение в 1. Затем цикл WHILE проверяет условие, и если оно TRUE , будет напечатан оператор печати. Когда цикл становится FALSE , будет напечатан следующий оператор после цикла WHILE. DECLARE @stud_value INT; Выполнение этого оператора вернет следующий вывод: В приведенном выше фрагменте кода цикла WHILE мы должны увеличивать значение переменной после каждой итерации. См. нижнюю часть приведенной выше строки кода как SET @stud_value = @stud_value + 1 . Если мы не напишем этот оператор, цикл будет выполняться бесконечно, потому что он не может стать FALSE. НАЧИНАТЬ Бесконечный цикл WHILEВозникает бесконечный цикл, когда оценка условия никогда не будет ложной. Следовательно, цикл никогда не закончится и будет выполняться вечно. Цикл в следующем фрагменте кода бесконечен, поскольку значение переменной не увеличивается. DECLARE @stud_value INT; Выполнение цикла отобразит следующий вывод. Этот цикл никогда не завершит свое выполнение, пока мы не отменим их выполнение запроса вручную. Вставка записей с помощью цикла WHILEМы также можем использовать цикл WHILE для вставки записей в определенную таблицу. Давайте посмотрим, как вставлять фиктивные записи в базу данных. Сначала мы создадим таблицу с именем ‘bikeshop’ , содержащую три столбца: Id, bike_name, и price . Выполните следующую инструкцию, чтобы создать эту таблицу: СОЗДАТЬ СТОЛ магазин велосипедов Далее мы будем использовать цикл WHILE для вставки десяти записей в эту таблицу, выполнив следующий скрипт: DECLARE @count INT; В этом коде мы объявили переменную @ count , а затем инициализировали ее значение 1 с помощью предложения SET. Затем мы должны определить тело цикла, которое выполняет инструкцию INSERT, чтобы добавить одну запись при каждом выполнении. Теперь мы можем проверить все записи таблицы bikeshop с помощью оператора SELECT. Он отобразит следующий вывод: Оператор BREAKSQL Server также позволяет нам использовать оператор BREAK в цикле WHILE, подобно языкам программирования. Это утверждение используется для немедленно останавливает текущую итерацию цикла , и поток управления возобновляется со следующего оператора после цикла. В общем, мы будем использовать оператор IF…ELSE , чтобы проверить, произошло ли условие. В следующем примере показано, как использовать оператор BREAK в цикле WHILE: DECLARE @count INT; Выполнение кода отобразит следующий вывод: Сначала в этом коде оценивается значение переменной. ПРОДОЛЖИТЬ ЗаявлениеSQL Server также позволяет нам использовать оператор CONTINUE в цикле WHILE, подобно языкам программирования. Этот оператор немедленно завершает текущее выполнение цикла при выполнении указанного условия , и поток управления возвращается к началу цикла. Как правило, оператор IF…ELSE будет использоваться для проверки того, было ли выполнено условие. Оператор CONTINUE в цикле WHILE демонстрируется в следующем примере. В этом примере мы предположим, что хотим использовать цикл WHILE для печатать только нечетные значения . Для этого можно использовать оператор CONTINUE. В этом примере сначала проверит , является ли значение переменной нечетным или четным . DECLARE @Count INT ) Выполнение фрагмента кода отобразит следующий вывод: Как реализовать пейджинг с циклом WHILE в SQL Server?Мы также можем использовать цикл WHILE для реализации пейджинга. Пейджинг позволяет отображать подмножество записей из таблицы в любой момент времени. Следующий пример пояснит эту концепцию. Цикл WHILE в коде будет выбирать две записи из таблицы bikeshop за раз. Выбранные записи затем отображаются в выходных данных. DECLARE @count INT Выполнение фрагмента кода вернет следующий вывод: Вложенный цикл WHILE Вложенный цикл WHILE в SQL Server — это просто цикл WHILE, записанный внутри другого цикла WHILE. Синтаксис Следующий синтаксис иллюстрирует работу вложенного цикла WHILE в SQL Server: В то время как выражение Давайте объясним этот синтаксис шаг за шагом: Шаг 1: Цикл начинается с проверки первого условия цикла WHILE, и если он находит ложный результат, он выходит из цикла While. В противном случае, если результат верен, управление переходит внутрь блока BEGIN и END для дальнейшего выполнения. Этот блок запустит выполнение второго цикла WHILE. См. шаг 2. Шаг 2: На этом шаге проверяется условие во вложенном цикле WHILE, и если оно ложно, второй цикл завершается и выполняется оператор вне этого. В противном случае, если результат верен, управление переходит внутрь блока BEGIN и END для дальнейшего выполнения. |