2010-02-25 5 views
2

Voici les données d'exemple. J'ai besoin de faire 3 copies de ces données en t sql sans utiliser la boucle et le retour en tant que résultat. Ceci est un exemple de données pas réel.Besoin de plusieurs copies d'un ensemble de résultats en SQL sans utiliser de boucle

42 South Yorkshire 
43 Lancashire 
44 Norfolk 

Edit: je besoin de plusieurs copies et je ne sais pas à l'avance que le nombre de copies je dois, je dois décider ce sur la base des dates. La date pourrait être du 1er janvier au 3 janvier OU du 1er janvier au 8 janvier

Merci.

Répondre

3

Ne sait pas mieux mais c'est certainement plus créatif! vous pouvez utiliser un CROSS JOIN.
EDIT: mettre du code pour générer une plage de dates, vous pouvez changer la plage de dates, les lignes du #date sont votre multiplicateur.

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 @[email protected]+1 
END 


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

drop table #data1 
drop table #dates 
+0

Ca me plaît, ça veut dire que la table principale n'est scannée qu'une seule fois. –

+0

Merci, c'est exactement ce que j'essayais de réaliser. – Kashif

1

Ce n'est peut-être pas la façon la plus efficace de le faire, mais cela devrait fonctionner.

(select ....) 
union all 
(select ....) 
union all 
(select ....) 
+0

Merci, Attendons mieux. – Kashif

0

On suppose que la table est nommé CountyPopulation:

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

Share and Enjoy.

2

Vous pouvez toujours utiliser un CTE pour faire le sale boulot

Remplacez le WHERE Counter < 4 avec la quantité de doublons dont vous avez besoin.

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

sympa, j'aime ça! –

+0

Merci, et bon, c'est un peu difficile pour moi mais j'essaierai certainement de comprendre l'expression de la table commune. – Kashif

+0

Pouvez-vous s'il vous plaît m'aider aussi à ce sujet. http: // stackoverflow.com/questions/2227808/get-top-one-record-of-same-fk-on-date-difference – Kashif

0

Il n'y a pas besoin d'utiliser un curseur. L'approche basée sur les ensembles consisterait à utiliser une table Calendrier. Alors d'abord, nous faisons notre table de calendrier qui doit être effectuée qu'une seule fois et être un peu permanent:

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 

Je peuplé avec une 100K dates qui va en 2300. Évidemment, vous pouvez toujours développer. Ensuite, nous générons nos données de test:

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 

Maintenant, le problème trivial devient:

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

De loin la meilleure solution est CROSS JOIN. Le plus naturel

Voir ma réponse ici: How to retrieve rows multiple times in SQL Server?

Si vous avez une table de nombres qui traînent, il est encore plus facile. Vous pouvez DATEDIFF les dates pour vous donner le filtre sur le tableau des nombres

+0

Merci pour le lien de l'autre question. – Kashif

Questions connexes