Вопрос или проблема
Как мне написать запрос SQL Server на основе столбца в таблице для того, чтобы вернуть нужное количество строк?
Предположим, что таблица имеет 2 строки с 3 столбцами. 3-й столбец указывает, сколько строк я хочу вернуть, и в этом 3-м столбце значения равны 3,2 (разные для каждой строки). Я хочу получить результат в 5 строк, где значения в столбцах 1 и 2 отображаются 3 раза, а в 1 и 2 — 2 раза. В итоге должно быть 5 строк. Я покажу данные в таблице ниже:
INSERT [dbo].[Table1] (InvoiceID, CompanyName, RowsNeeded) VALUES ('A1000', 'Компания 1', 3)
INSERT [dbo].[Table1] (InvoiceID, CompanyName, RowsNeeded) VALUES ('A1001', 'Компания 2', 2)
возвращаемый набор результатов:
'A1000','Компания 1'
'A1000','Компания 1'
'A1000','Компания 1'
'A1001','Компания 2'
'A1001','Компания 2'
Можно использовать рекурсивный иерархический CTE:
WITH cte (InvoiceID, CompanyName, RowsNeeded, level) AS (
SELECT InvoiceID, CompanyName, RowsNeeded, 1 AS level
FROM Table1
UNION ALL
SELECT t2.InvoiceID, t2.CompanyName, t2.RowsNeeded, t2.level + 1
FROM Table1 t1
INNER JOIN cte t2
ON t2.InvoiceID = t1.InvoiceID AND
t1.level + 1 <= t1.RowsNeeded
)
SELECT InvoiceID, CompanyName
FROM cte
ORDER BY InvoiceID;
Стратегия здесь состоит в том, чтобы просто воспроизводить каждую запись счета RowsNeeded
указанное количество раз.
Вы можете использовать рекурсивный CTE:
with cte as (
select InvoiceID, CompanyName, RowsNeeded, 1 as rn
from [dbo].[Table1]
union all
select InvoiceID, CompanyName, RowsNeeded, rn + 1 as rn
from cte
where rn < RowsNeeded
)
select InvoiceID, CompanyName
from cte
order by InvoiceID, CompanyName
вывод:
InvoiceID | CompanyName |
---|---|
A1000 | Компания 1 |
A1000 | Компания 1 |
A1000 | Компания 1 |
A1001 | Компания 2 |
A1001 | Компания 2 |
Используйте:
WITH RecursiveCTE AS (
SELECT InvoiceID, CompanyName, RowsNeeded, 1 AS RowNumber
FROM Table1
UNION ALL
SELECT t.InvoiceID, t.CompanyName, t.RowsNeeded, RowNumber + 1
FROM RecursiveCTE r
JOIN Table1 t ON r.InvoiceID = t.InvoiceID
WHERE RowNumber < t.RowsNeeded
)
SELECT InvoiceID, CompanyName
FROM RecursiveCTE
ORDER BY InvoiceID
OPTION (MAXRECURSION 0);
Ответ или решение
Чтобы создать SQL-запрос, который позволяет вернуть определенное количество строк на основе значений в третьем столбце таблицы, можно использовать рекурсивный обобщенный табличный выражение (CTE) в SQL Server. Ваша задача заключается в репликации записей, основанных на значении столбца RowsNeeded
, который указывает, сколько строк вы хотите вернуть для каждой записи.
Вот пример, который демонстрирует, как это сделать на основе вашей таблицы Table1
:
WITH RecursiveCTE AS (
-- Начальный запрос: выбираем строки из основной таблицы с начальным уровнем (RowNumber) равным 1
SELECT InvoiceID, CompanyName, RowsNeeded, 1 AS RowNumber
FROM Table1
UNION ALL
-- Рекурсивный запрос: добавляем повторные строки, увеличивая счетчик (RowNumber) на 1, до тех пор, пока он не достигнет значения RowsNeeded
SELECT r.InvoiceID, r.CompanyName, r.RowsNeeded, RowNumber + 1
FROM RecursiveCTE r
JOIN Table1 t ON r.InvoiceID = t.InvoiceID
WHERE RowNumber < t.RowsNeeded
)
-- Часть для выбора итоговых данных
SELECT InvoiceID, CompanyName
FROM RecursiveCTE
ORDER BY InvoiceID, RowNumber
OPTION (MAXRECURSION 0); -- Для предотвращения ограничения на рекурсию
Объяснение кода:
-
Инициализация CTE:
- В первом запросе выбираются
InvoiceID
,CompanyName
иRowsNeeded
из таблицыTable1
, при этомRowNumber
инициализируется значением 1.
- В первом запросе выбираются
-
Рекурсивная часть:
- Второй запрос использует рекурсию для добавления строк. Здесь мы соединяем рекурсивный CTE с основной таблицей по
InvoiceID
, и добавляем строки, увеличиваяRowNumber
до тех пор, пока он остается меньше, чем значениеRowsNeeded
.
- Второй запрос использует рекурсию для добавления строк. Здесь мы соединяем рекурсивный CTE с основной таблицей по
-
Финальный выбор:
- В последней части выбираются
InvoiceID
иCompanyName
из полученного CTE, и вывод сортируется поInvoiceID
иRowNumber
.
- В последней части выбираются
-
Опция MAXRECURSION:
- Установка
OPTION (MAXRECURSION 0)
позволяет выполнять рекурсию без ограничений, что важно, если ваши данные содержат высокие значения вRowsNeeded
.
- Установка
Результат:
Данный запрос возвратит строки в ожидаемом формате, где каждая запись будет повторена RowsNeeded
раз, что обеспечит итоговое количество строк, равное 5 для предоставленных вами данных.
Теперь вы сможете использовать этот подход, чтобы динамически возвращать строки в зависимости от значений в вашей таблице.