Нужно несколько копий одного набора результатов в SQL без использования цикла - PullRequest
2 голосов
/ 25 февраля 2010

Ниже приведен пример данных. Мне нужно сделать 3 копии этих данных в t sql без использования цикла и вернуть как один набор результатов. Это пример данных не реально.

42  South Yorkshire
43  Lancashire
44  Norfolk

Редактировать: мне нужно несколько копий, и я заранее не знаю, сколько мне нужно копий, чтобы решить это на основе дат. Дата может быть с 1 января по 3 января ИЛИ с 1 января по 8 января.

Спасибо.

Ответы [ 6 ]

3 голосов
/ 25 февраля 2010

Не знаю о лучше , но это определенно более креативно! Вы можете использовать CROSS JOIN .
РЕДАКТИРОВАТЬ: ввести некоторый код для создания диапазона дат, вы можете изменить диапазон дат, строки в #date ваш множитель.

  declare @startdate datetime
, @enddate datetime
create table #data1 ([id] int , [name] nvarchar(100))
create table #dates ([date] datetime)


INSERT #data1 SELECT 42,  'South Yorkshire'
INSERT #data1 SELECT 43,  'Lancashire'
INSERT #data1 SELECT 44,  'Norfolk'


set @startdate = '1Jan2010'
set @enddate = '3Jan2010'

WHILE (@startdate <= @enddate)
BEGIN   
INSERT #dates SELECT @startdate
set @startdate=@startdate+1
END


SELECT [id] , [name] from #data1 cross join #dates

drop table #data1
drop table #dates
2 голосов
/ 25 февраля 2010

Вы всегда можете использовать CTE , чтобы сделать грязную работу

Замените WHERE Counter < 4 на количество дубликатов, которое вам нужно.

CREATE TABLE City (ID INTEGER PRIMARY KEY, Name VARCHAR(32))

INSERT INTO City VALUES (42, 'South Yorkshire')
INSERT INTO City VALUES (43, 'Lancashire')
INSERT INTO City VALUES (44, 'Norfolk')

/*
  The CTE duplicates every row from CTE for the amount
  specified by Counter
*/
;WITH CityCTE (ID, Name, Counter) AS 
(
  SELECT  c.ID, c.Name, 0 AS Counter
  FROM    City c
  UNION ALL 
  SELECT  c.ID, c.Name, Counter + 1
  FROM    City c  
          INNER JOIN CityCTE cte ON cte.ID = c.ID
  WHERE   Counter < 4
)
SELECT  ID, Name
FROM    CityCTE
ORDER BY 1, 2

DROP TABLE City
1 голос
/ 25 февраля 2010

Возможно, это не самый эффективный способ сделать это, но он должен работать.

(select ....)
union all
(select ....)
union all
(select ....)
0 голосов
/ 25 февраля 2010

На сегодняшний день лучшим решением является CROSS JOIN. Самый естественный.

Смотрите мой ответ здесь: Как получить строки несколько раз в SQL Server?

Если у вас есть таблица чисел, это еще проще. Вы можете DATEDIFF даты, чтобы дать вам фильтр в таблице чисел

0 голосов
/ 25 февраля 2010

Нет необходимости использовать курсор. Основанный на множестве подход будет состоять в том, чтобы использовать таблицу Календаря. Итак, сначала мы создаем нашу календарную таблицу, которая должна быть сделана только один раз и должна быть несколько постоянной:

Create Table dbo.Calendar ( Date datetime not null Primary Key Clustered )
GO
; With Numbers As
(
Select ROW_NUMBER() OVER( ORDER BY S1.object_id ) As [Counter]
From sys.columns As s1
 Cross Join sys.columns As s2
)
Insert dbo.Calendar([Date])
Select DateAdd(d, [Counter], '19000101')
From Numbers
Where [Counter] <= 100000
GO

Я заполнил его датами 100K, которые входят в 2300. Очевидно, вы всегда можете расширить его. Далее мы генерируем наши тестовые данные:

Create Table dbo.Data(Id int not null, [Name] nvarchar(20) not null)
GO
Insert dbo.Data(Id, [Name]) Values(42,'South Yorkshire')
Insert dbo.Data(Id, [Name]) Values(43, 'Lancashire')
Insert dbo.Data(Id, [Name]) Values(44, 'Norfolk')
GO

Теперь проблема становится тривиальной:

Declare @Start datetime
Declare @End datetime
Set @Start = '2010-01-01'
Set @End = '2010-01-03'
Select Dates.[Date], Id, [Name]
From dbo.Data
 Cross Join (
              Select [Date]
              From dbo.Calendar
              Where [Date] >= @Start
              And [Date] <= @End
             ) As Dates
0 голосов
/ 25 февраля 2010

Предположим, что таблица называется CountyPopulation:

SELECT * FROM CountyPopulation
UNION ALL
SELECT * FROM CountyPopulation
UNION ALL
SELECT * FROM CountyPopulation

Делись и наслаждайся.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...