Member 13486774 Ответов: 2

Sql - вложенный цикл


У меня есть столик

Таблица А
--------
Один
Б
С
Д

Мне нужна таблица результатов, как показано ниже

Таблица А
--------
Один
Б
С
Д
AB
ДО Н.Э.
КОМПАКТ-ДИСК
АЗБУКА
BCD
ABCD


Любая помощь будет оценена по достоинству.

Что я уже пробовал:

Я попытался привести комбинацию из двух слов.

DECLARE @tbl_wordlist TABLE (
    [Id]        int identity,
    [Word]   nvarchar(max)
)
INSERT INTO @tbl_wordlist
SELECT [Data] FROM Split('A B C D', ' ')

-- LOGIC :::::: USING WHILE LOOP, GROUP TWO-TWO WORDS AND THEN INSERT INTO THE SAME TABLE
DECLARE @MaxCount INTEGER
DECLARE @Count INTEGER, @I INT
DECLARE @Txt VARCHAR(MAX)
SET @Count = 1
SET @I = 2
SET @Txt = (SELECT [Word] FROM @tbl_wordlist WHERE ID = @Count AND [Word] IS NOT NULL)
SET @MaxCount = (SELECT MAX(ID) FROM @tbl_wordlist) 
WHILE @Count<@MaxCount
    BEGIN
    IF @Txt!=''
        SET @Txt=@Txt+' ' + (SELECT [Word] FROM @tbl_wordlist WHERE ID = (@I))
    ELSE
        SET @Txt=(SELECT [Word] FROM @tbl_wordlist WHERE ID=@Count)
    SET @Count=@Count+1
    SET @I=@I+1
    INSERT INTO @tbl_wordlist([Word])Values(@Txt)
    SET @Txt = (SELECT [Word] FROM @tbl_wordlist WHERE ID = @Count AND [Word] IS NOT NULL)
    END

SELECT * FROM @tbl_wordlist;

Karthik_Mahalingam

А как насчет переменного тока,bd,... и т. д

Member 13486774

Нет. Я просто хочу, чтобы последовательные слова были вместе.

CHill60

Вам вообще не нужны никакие петли. Когда я доберусь до ноутбука я попытаюсь опубликовать решение

2 Ответов

Рейтинг:
5

itsmypassion

Модифицированный, пожалуйста, попробуйте

DECLARE @tbl_wordlist TABLE (
    [Id]        int identity,
    [Word]   nvarchar(max)
)
INSERT INTO @tbl_wordlist
SELECT [Data] FROM Split--('A B C D', ' ')
 
DECLARE @COUNTER AS INTEGER

DECLARE @RUNNINGCOUNTER AS INTEGER 
DECLARE @NUMBEROFRUNS AS INTEGER = 1

--DECLARE @INNERCOUNTER AS INTEGER
DECLARE @TOTAL AS INTEGER  = (SELECT COUNT(*) FROM SPLIT)

SET @RUNNINGCOUNTER = (SELECT COUNT(*) FROM SPLIT)
sET @COUNTER = 1

DECLARE @WORD AS VARCHAR(MAX)

WHILE @RUNNINGCOUNTER > 0
BEGIN
	SET @NUMBEROFRUNS = 1
	WHILE @NUMBEROFRUNS <= @RUNNINGCOUNTER -1
	BEGIN

		SET @WORD = ''		
		SET @COUNTER = 1
		SET @WORD =''
		
		--PRINT 'RUN Counter '  + cast (@NUMBEROFRUNS as nvarchar(10))
		
		WHILE @COUNTER <= @TOTAL - (@RUNNINGCOUNTER -2)
		BEGIN
		--PRINT 'Counter '  + cast (@cOUNTER as nvarchar(10))
			SET @WORD = @WORD  + (SELECT WORD FROM @tbl_wordlist 
			WHERE ID =@NUMBEROFRUNS -1 + @COUNTER)
			SET @COUNTER=@COUNTER+1
		END
	
		pRINT @WORD
		INSERT INTO @tbl_wordlist (WORD) VALUES(@WORD)	
		
		
		SET @NUMBEROFRUNS =@NUMBEROFRUNS +1
	END
	
	SET @NUMBEROFRUNS = 1
	SET @RUNNINGCOUNTER = @RUNNINGCOUNTER -1
END
sELECT * FROM @tbl_wordlist


Member 13486774

Привет @itsmypassion , Спасибо за ответ. Код потрясающий, но он дает другой шаблон, чем то, что я хочу.
Это дает

Таблица А
---------
Один
Б
С
Д
Один
AB
АЗБУКА
ABCD

itsmypassion

ОК

Member 13486774

Это сработало как заклинание. Большое спасибо. Я бы никогда этого не сделал.

Рейтинг:
1

CHill60

Я знаю, что вы уже приняли ответ, но, как я сказал вчера, есть еще один ответ. нет необходимости использовать петлю на самом деле количество раз , когда вам нужно использовать любой цикл в SQL, очень редко - потому что он основан на наборе.

Очень простой способ получения результата-это просто использовать серию самосоединений...

-- Get the AB, BC, CD entries with a self join
INSERT INTO @tbl_wordlist 
SELECT A.Word + B.Word FROM @tbl_wordlist A
LEFT OUTER JOIN @tbl_wordlist B ON A.Id + 1 = B.Id
WHERE B.Word IS NOT NULL

-- Get the ABC, BCD entries with another self join
INSERT INTO @tbl_wordlist 
select A.Word + B.Word
from @tbl_wordlist A
LEFT OUTER JOIN @tbl_wordlist B ON A.Id + 5 = B.Id	-- NB The 5 here is important!
WHERE B.Word IS NOT NULL

-- Get the ABCD entry with yet another self join
INSERT INTO @tbl_wordlist 
select A.Word + B.Word
from @tbl_wordlist A
LEFT OUTER JOIN @tbl_wordlist B ON A.Id + 8 = B.Id	-- NB The 8 here is also important!
WHERE B.Word IS NOT NULL
Есть и другие, лучшие подходы, которые можно было бы использовать, это только первое, что пришло на ум.

Если это ваша домашняя работа, то ваш наставник, вероятно, скоро начнет учить вас большему количеству комбинаций, и им абсолютно не нужно, чтобы вы сохраняли циклы кодирования в SQL (если они это сделают, то покинут этот колледж!). Я так увлекся использованием петель, что написал об этом статью - Циклы обработки в SQL Server[^] - моя статья касается только поверхности того, что можно сделать (что должен быть сделано) в SQL, не приближаясь к обычному "циклу", поэтому сделайте больше исследований.