Benutzer mit den meisten Antworten
Print ausgabe einer Variable übergeben

Frage
-
Hallo an alle,
leider ist mir kein besserer Titel eingefallen aber vielleicht zeigt er ja doch auf was für ein Vorhaben ich habe. Ziel ist es mit einer While und If Schleife mir eine SQL Statement selber zu erstellen.
declare @Monat int =2 declare @Jahr int =2012 declare @Tag_anzahl int =28 declare @test int=0 declare @i int = 0 declare @SQL nvarchar(4000) --SET @SQL=() while @i <= @Tag_anzahl Begin if @i <@Tag_anzahl Begin PRINT @i PRINT 'as Tag union select' SET @i=@i+1 END else if @i = @Tag_anzahl Begin PRINT @i PRINT 'as Tag' SET @i=@i+1 END END
Die Ausgabe klappt aber wie bekomme ich das nun eine Variable oder wie bekomme ich das Aufgerufen? So das am Ende auch wirklich das Select abgesetzt wird und ich mit dem Ergebnis weiterarbeiten kann? Oder wie heißt die Technik die ich einsetzen muss damit ich mich bei Datenkrake und Co umschauen kann?
Antworten
-
Das geht ganz einfach. Hier nur der letzte Teil des Statements:
With ... Select n1.n as Tag, n2.Stunde from Numbers n1 cross join (Select n as Stunde from Numbers where n <= 24) as n2 where n <= 28 order by Tag, Stunde;
Einen schönen Tag noch,
Christoph
--
Microsoft SQL Server MVP - http://www.insidesql.org/blogs/cmu- Als Antwort markiert Toot_Braunstein Mittwoch, 25. März 2015 14:47
Alle Antworten
-
Das finde ich viel zu kompliziert. Schau Dir mal das hier an:
with t0(n) as ( select 1 union all -- Erzeugt zwei Sätze = 2^1 select 1 ), t1(n) as ( select 1 -- Cross Join erzeugt 4 Sätze = 2^2 from t0 as a, t0 as b ), t2(n) as ( select 1 -- Cross Join erzeugt 16 Sätze = 2^4 from t1 as a, t1 as b ), t3(n) as ( select 1 -- Cross Join erzeugt 256 Sätze = 2^8 from t2 as a, t2 as b ), Numbers(n) as ( Select row_number() over (order by n) as n from t3 ) Select n as Tag from Numbers where n <= 28;
Durch entsprechende Ergänzungen kannst du das sehr schnell erweitern. Packe es dann noch in eine User Defined Function und Dir stehen alle Möglichkeiten offen.
-- -- Ändere das letzte Select so ab, dass die Werte von 1000 bis 1099 ausgeben werden -- with t0(n) as ( select 1 union all -- Erzeugt zwei Sätze = 2^1 select 1 ), t1(n) as ( select 1 -- Cross Join erzeugt 4 Sätze = 2^2 from t0 as a, t0 as b ), t2(n) as ( select 1 -- Cross Join erzeugt 16 Sätze = 2^4 from t1 as a, t1 as b ), t3(n) as ( select 1 -- Cross Join erzeugt 256 Sätze = 2^8 from t2 as a, t2 as b ), Numbers(n) as ( Select row_number() over (order by n) as n from t3 ) Select 1000 + n - 1 as n from Numbers where n <= 1099 - 1000 + 1 ; ----------------------------------------------------------------------------------------------------------------------------------------------- -- -- Create Function muss die einzige Anweisung im Batch sein -- go -- -- Erzeuge eine Funktion "udf_Numbers", welche das eben erstellte Statement verwendet -- In der Beispiellösung sind die CTE bis auf 2^32 Sätze erweitert -- Ersetze 1000 mit @from und @1099 mit @to -- -- Schemabinding ist hier eigentlich überflüssig, aber eine sonst sinnvolle Sicherheitsmassnahme. -- CREATE FUNCTION unterstützt eine SCHEMABINDING-Klausel, die die Funktion an das Schema von Objekten bindet, auf die verwiesen wird, -- wie z. B. Tabellen, Sichten und andere benutzerdefinierte Funktionen. Der Versuch, ein Objekt zu ändern oder zu löschen, auf das -- von einer schemagebundenen Funktion verwiesen wird, erzeugt einen Fehler. -- create function udf_Numbers ( @from as bigint, @to as bigint ) returns table with schemabinding as return with t0(n) as ( select 1 union all -- Erzeugt zwei Sätze = 2^1 select 1 ), t1(n) as ( select 1 -- Cross Join erzeugt 4 Sätze = 2^2 from t0 as a, t0 as b ), t2(n) as ( select 1 -- Cross Join erzeugt 16 Sätze = 2^4 from t1 as a, t1 as b ), t3(n) as ( select 1 -- Cross Join erzeugt 256 Sätze = 2^8 from t2 as a, t2 as b ), t4(n) as ( select 1 from t3 as a, t3 as b -- Cross Join erzeugt 65.536 Sätze = 2^16 ), t5(n) as ( select 1 from t4 as a, t4 as b -- Cross Join erzeugt 4.294.967.296 Sätze = 2^32 ), Numbers(n) as -- nummeriert die Sätze durch beginnend bei 1 ( select row_number() over (order by n) as n from t5 ) select @from + n - 1 as n -- addiert die laufende Nummer auf den Startwert from Numbers where n <= @to - @from + 1 -- so lange die Anzahl der Zeilen eingehalten wird go ----------------------------------------------------------------------------------------------------------------------------------------------- -- Teste die Funktion mit verschiedenen Werten -- select * from udf_Numbers(1,101); -- -- Erzeuge mir die Daten für 90 Tage ab Startdatum 01.01.2013 -- select dateadd(dd,n,'20130101') as Kalender from udf_Numbers(0,89); -- -- Erzeuge mir die Daten für die Tage 10..90 ab Startdatum 01.01.2013 -- select dateadd(dd,n,'20130101') as Kalender from dbo.udf_Numbers(10,90);
Das Original ist von Steve Kass.
Einen schönen Tag noch,
Christoph
--
Microsoft SQL Server MVP - http://www.insidesql.org/blogs/cmu- Als Antwort vorgeschlagen Stefan FalzModerator Mittwoch, 25. März 2015 18:26
-
Hallo Christoph das Skript ist klasse (da wäre ich im Leben nicht drauf gekommen) jedoch lässt sich dies doch leider nicht vereinbaren mit meinen weiteren plänen. Oder bekommt man es hin das man auch die Uhrzeit in voller Stunde in einer weiteren Tabelle abgebildet bekommt?
zb.
Tag volle_Stunde
1 1
1 2
1 3
.
.
.
31 23
-
Das geht ganz einfach. Hier nur der letzte Teil des Statements:
With ... Select n1.n as Tag, n2.Stunde from Numbers n1 cross join (Select n as Stunde from Numbers where n <= 24) as n2 where n <= 28 order by Tag, Stunde;
Einen schönen Tag noch,
Christoph
--
Microsoft SQL Server MVP - http://www.insidesql.org/blogs/cmu- Als Antwort markiert Toot_Braunstein Mittwoch, 25. März 2015 14:47
-
Hallo Christoph leider habe ich jetzt erfahren das nun die Zeit doch von 0 Uhr gemessen wird.
Soll heißen es müsste nun so aussehen
Tag volleStunde
1 0
1 1
.
.
.
31 23
leider geht das mit deinem Skript nicht da er ja immer "erst" ab der 1.sten vollen Stunde anzeigt. Hast du vielleicht noch eine andere Lösung?
-
Hallo! Hier ist ein klein bisschen Kreativität gefragt. Wieder nur ein Teil des Statements:
cross join (Select n-1 as Stunde
Einen schönen Tag noch,
Christoph
--
Microsoft SQL Server MVP - http://www.insidesql.org/blogs/cmu