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 — это оператор потока управления, используемый для многократного выполнения набора операторов до тех пор, пока не будет выполнено заданное условие . Этот цикл начинается с заданного условия, оцените его, и если оно ИСТИНА, операторы перейдут внутрь цикла для дальнейшего выполнения. Если условие становится FALSE, оно не будет выполняться. Это означает, что цикл while в SQL Server может выполняться ноль или более раз.

Блок-схема цикла WHILE

Следующая блок-схема объясняет полный рабочий процесс цикла WHILE в SQL Server:

На этой диаграмме видно, что указанное условие проверяется для каждой итерации, и на основе результата оценки определяется поток кода. Если результат оценивается как TRUE, поток управления переходит внутрь цикла для дальнейшего выполнения. Если оцениваемый результат равен FALSE, поток управления выйдет из цикла, и будет выполнен любой оператор или запрос вне цикла.

Синтаксис

Следующий синтаксис иллюстрирует цикл WHILE в SQL Server:

ПОКА логическое_условие
НАЧИНАТЬ
{выражение_SQL | блок_операторов | ПЕРЕРЫВ | ПРОДОЛЖАТЬ}
КОНЕЦ;

В этом синтаксисе у нас есть следующие параметры или аргументы:

  • логическое_условие: Это обязательное условие, которое будет проверяться на каждой итерации, чтобы вернуть результат ИСТИНА или ЛОЖЬ. Если это оператор SELECT, он должен быть заключен в круглые скобки.
  • sql_statement или statement_block: Оператор или группа SQL определяются внутри ключевых слов BEGIN и END. Он будет выполняться на каждой итерации, пока цикл не станет FALSE.
  • Break: Мгновенно завершает самый внутренний цикл, и поток управления возобновляется со следующего оператора после цикла.
  • Продолжить: Переход к следующей итерации без пропуска оставшихся операторов внутри цикла. Обычно это приводит к перезапуску цикла с самого начала.

Пример цикла WHILE

Давайте разберемся, как работает цикл WHILE в SQL Server, на примере. В данном примере мы сначала объявили значение целочисленного типа и установили его значение в 1. Затем цикл WHILE проверяет условие, и если оно TRUE , будет напечатан оператор печати. Когда цикл становится FALSE , будет напечатан следующий оператор после цикла WHILE.

DECLARE @stud_value INT;
УСТАНОВИТЬ @stud_value = 1;
ПОКА @stud_value

Выполнение этого оператора вернет следующий вывод:

В приведенном выше фрагменте кода цикла WHILE мы должны увеличивать значение переменной после каждой итерации. См. нижнюю часть приведенной выше строки кода как SET @stud_value = @stud_value + 1 . Если мы не напишем этот оператор, цикл будет выполняться бесконечно, потому что он не может стать FALSE.

НАЧИНАТЬ
ПЕЧАТЬ ‘Марк Генри’;
SET @stud_value = @stud_value + 1;
КОНЕЦ;

Бесконечный цикл WHILE

Возникает бесконечный цикл, когда оценка условия никогда не будет ложной. Следовательно, цикл никогда не закончится и будет выполняться вечно. Цикл в следующем фрагменте кода бесконечен, поскольку значение переменной не увеличивается.

DECLARE @stud_value INT;
УСТАНОВИТЬ @stud_value = 1;
ПОКА @stud_value

Выполнение цикла отобразит следующий вывод. Этот цикл никогда не завершит свое выполнение, пока мы не отменим их выполнение запроса вручную.

Вставка записей с помощью цикла WHILE

Мы также можем использовать цикл WHILE для вставки записей в определенную таблицу. Давайте посмотрим, как вставлять фиктивные записи в базу данных. Сначала мы создадим таблицу с именем ‘bikeshop’ , содержащую три столбца: Id, bike_name, и price . Выполните следующую инструкцию, чтобы создать эту таблицу:

СОЗДАТЬ СТОЛ магазин велосипедов
(
Id INT PRIMARY KEY IDENTITY,
имя_велосипеда VARCHAR (50) НЕ НУЛЕВОЕ,
цена с плавающей запятой
)

Далее мы будем использовать цикл WHILE для вставки десяти записей в эту таблицу, выполнив следующий скрипт:

DECLARE @count INT;
УСТАНОВИТЬ @количество = 1;
ПОКА @count

В этом коде мы объявили переменную @ count , а затем инициализировали ее значение 1 с помощью предложения SET. Затем мы должны определить тело цикла, которое выполняет инструкцию INSERT, чтобы добавить одну запись при каждом выполнении. Столбец bike_name добавит значение переменной @count со строкой 9.0003 Bike , а столбец price определяется значением переменной @count, умноженным на 5000 . Цикл будет выполняться до тех пор, пока значение переменной @count не станет FALSE. Это означает, что цикл WHILE будет выполнен десять раз и вставит десять записей в таблицу bikeshop.

Теперь мы можем проверить все записи таблицы bikeshop с помощью оператора SELECT. Он отобразит следующий вывод:

Оператор BREAK

SQL Server также позволяет нам использовать оператор BREAK в цикле WHILE, подобно языкам программирования. Это утверждение используется для немедленно останавливает текущую итерацию цикла , и поток управления возобновляется со следующего оператора после цикла. В общем, мы будем использовать оператор IF…ELSE , чтобы проверить, произошло ли условие.

В следующем примере показано, как использовать оператор BREAK в цикле WHILE:

DECLARE @count INT;
УСТАНОВИТЬ @количество = 1;
ПОКА @count = 6
НАЧИНАТЬ
ПЕРЕРЫВ
КОНЕЦ
УСТАНОВИТЬ @Count = @Count + 1
КОНЕЦ;

Выполнение кода отобразит следующий вывод:

Сначала в этом коде оценивается значение переменной. Если оно TRUE, элемент управления входит в цикл и печатает оператор. Когда значение переменной больше или равно 6, управление переходит в блок IF…ELSE и выполняет оператор BREAK для завершения цикла. Если блок IF…ELSE не удовлетворяет условию; затем цикл будет продолжать работать до тех пор, пока условие не изменится на FALSE.

ПРОДОЛЖИТЬ Заявление

SQL Server также позволяет нам использовать оператор CONTINUE в цикле WHILE, подобно языкам программирования. Этот оператор немедленно завершает текущее выполнение цикла при выполнении указанного условия , и поток управления возвращается к началу цикла. Как правило, оператор IF…ELSE будет использоваться для проверки того, было ли выполнено условие.

Оператор CONTINUE в цикле WHILE демонстрируется в следующем примере. В этом примере мы предположим, что хотим использовать цикл WHILE для печатать только нечетные значения . Для этого можно использовать оператор CONTINUE. В этом примере сначала проверит , является ли значение переменной нечетным или четным . Если оно четное, выполнение переходит в блоки операторов IF…ELSE и уменьшает значение переменной на единицу. Затем он выполнит оператор CONTINUE и начнет новую итерацию с самого начала.

DECLARE @Count INT
УСТАНОВИТЬ @Count = 1
ПОКА (@Count

)

Выполнение фрагмента кода отобразит следующий вывод:

Как реализовать пейджинг с циклом WHILE в SQL Server?

Мы также можем использовать цикл WHILE для реализации пейджинга. Пейджинг позволяет отображать подмножество записей из таблицы в любой момент времени. Следующий пример пояснит эту концепцию. Цикл WHILE в коде будет выбирать две записи из таблицы bikeshop за раз. Выбранные записи затем отображаются в выходных данных.

DECLARE @count INT
ОБЪЯВИТЬ @limit INT;
УСТАНОВИТЬ @количество = 0
УСТАНОВИТЬ @лимит = 2;
ПОКА @count

Выполнение фрагмента кода вернет следующий вывод:

Вложенный цикл WHILE

Вложенный цикл WHILE в SQL Server — это просто цикл WHILE, записанный внутри другого цикла WHILE. Когда мы работаем с многоуровневыми данными, вложенные циклы WHILE необходимы. Поскольку эта концепция полезна при извлечении многоуровневых данных, когда мы хотим их выбрать, рекомендуется соблюдать осторожность при использовании вложенного цикла.

Синтаксис

Следующий синтаксис иллюстрирует работу вложенного цикла WHILE в SQL Server:

В то время как выражение
НАЧИНАТЬ
ПОКА @Val2

Давайте объясним этот синтаксис шаг за шагом:

Шаг 1: Цикл начинается с проверки первого условия цикла WHILE, и если он находит ложный результат, он выходит из цикла While. В противном случае, если результат верен, управление переходит внутрь блока BEGIN и END для дальнейшего выполнения. Этот блок запустит выполнение второго цикла WHILE. См. шаг 2.

Шаг 2: На этом шаге проверяется условие во вложенном цикле WHILE, и если оно ложно, второй цикл завершается и выполняется оператор вне этого. В противном случае, если результат верен, управление переходит внутрь блока BEGIN и END для дальнейшего выполнения.

Imacros | Все права защищены © 2021