| 

.NET C# Java Javascript Exception

5
Hallo,

ich suche verzweifelt nach eine Lösung für folgendes Problem.
Eine SELECT Abfrage
SELECT Name, Anzahl FROM Tabelle

gibt folgendes Ergebnis aus:

Name Anzahl
----------------
Meier 5
Müller 1
Schmidt 2

Jetzt kommt das knifflige. Ich möchte jetzt eine Abfrage haben bei der das folgende Ergebnis raus kommt

Name
--------
Meier
Meier
Meier
Meier
Meier
Müller
Schmidt
Schmidt

Kann ich das im SQL machen oder brauch ich da doch wo anders Logik?

Danke schonmal

gruss Mario
03.05.2011
mario_kaempfer 273 8
4 Antworten
5
Hier ein Lösungsvorschlag mit Common Table Expressions:

Erstmal die Temp-Tabelle die ich zum testen genommen habe:
create table #t(name varchar(20), anzahl int)
insert into #t VALUES ('Meier',5)
insert into #t VALUES ('Müller',1)
insert into #t VALUES ('Schmidt',2)

Und das Statement:
WITH THierarchy (Name, Anz, HierarchyLevel) AS
(
SELECT t.name, t.anzahl, 1 HierarchyLevel
FROM #t t

UNION ALL

SELECT t.name, t.anzahl, th.HierarchyLevel + 1 AS HierarchyLevel
FROM #t t
INNER JOIN THierarchy th ON th.HierarchyLevel<th.anz AND t.name = th.Name
)

SELECT Name, HierarchyLevel
FROM THierarchy
ORDER BY Name

Ergebniss:
Meier 1
Meier 2
Meier 3
Meier 4
Meier 5
Müller 1
Schmidt 1
Schmidt 2
03.05.2011
Floyd 14,5k 3 9
Floyd 14,5k 3 9
1
Das Funktioniert soweit super nur wenn ich ein Datensatz mit mehr als 100 Positionen habe dann kommt das die maximale Rekursionstiefe erreicht ist.

Ansonsten super :)
mario_kaempfer 03.05.2011
Das ist einfach :D. Häng hinter das "Order BY NAME" noch "option (maxrecursion 0)" daran. Damit wir die maximale Rekursionstiefe auf unendlich gesetzt.
Floyd 03.05.2011
Siehe dazu auch: http://books.google.de/books?id=Z1_ZQnpa12UC&pg=PA379&lpg=PA379&dq=CTE+Rekursionstiefe&source=bl&ots=jMeScAbNli&sig=7iKWeSxCU5_5SlQOxl21GOWMKyM&hl=de&ei=J8O_Tc-2LsTrsgbB_KXDBQ&sa=X&oi=book_result&ct=result&resnum=2&ved=0CBwQ6AEwAQ#v=onepage&q=CTE%20Rekursionstiefe&f=false (Das SQL Server 2005-Entwicklerbuch - Von Bob Beauchemin,Dan Sullivan)
Floyd 03.05.2011
Interessant ist insbesondere auch die Möglichkeit einer Duplizierung zwischen Intervallen:

WITH THierarchy (ID, GültigVon,GültigBis, GültigImJahr) AS
(
SELECT M.ID,M.GültigVon,M.GültigBis, YEAR(M.GültigVon) GültigImJahr
FROM dbo.someTable AS M

UNION ALL
SELECT M.ID,M.GültigVon,M.GültigBis, th.GültigImJahr+1 GültigImJahr
FROM dbo.someTable AS M

INNER JOIN THierarchy th ON th.GültigImJahr<YEAR(M.GültigBis) AND M.ID = th.ID
)

SELECT ID,GültigVon,GültigBis, GültigImJahr
FROM THierarchy
ORDER BY ID,GültigImJahr
Dominik.Hilke 20.09.2012
1
Hier eine Variante mit gespeicherter Prozedur.

Erst die Prozedur erstellen:

SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO

-- =============================================
-- Author: Hilke, Dominik
-- Create date: 11.3.2011
-- Description: <Description,,>
-- =============================================
CREATE FUNCTION [dbo].[RowExplode]
(
-- Add the parameters for the function here
@Number int
)
RETURNS @exploded TABLE (Rownumber int)

AS
BEGIN
DECLARE @i int;

SET @i=0;
WHILE @i<@Number
BEGIN
SET @i=@i+1
INSERT INTO @exploded (Rownumber) VALUES (@i)
END
RETURN
END

GO


Anschließend Die Tabelle so abfragen:

SELECT TOP (100) PERCENT T.Name, T.Anzahl, r.RowNumber
FROM dbo.Tabelle T CROSS APPLY dbo.RowExplode(ISNULL(T.Anzahl, 0)) r
04.05.2011
Dominik.Hilke 131 2
+1, auch kein schlechter Ansatz
Floyd 04.05.2011
0
Hi Mario,

vielleicht hilft dir ein cursor weiter. Damit könntest du dir eine Abfrage zusammenbauen, die in die richtung geht.

select 'meier'
union
select 'meier'
...

lg
03.05.2011
mrmee 735 8
0
eventuell könntest du einen join auf ein subselect machen, wo du ungefähr so arbeitest:

(könnte sein, dass dies ein bisserl oracle lastig ist, vielleicht musst du für t-sql ein bisserl noch die syntax ändern)

SELECT ht.Name, t.Anzahl FROM Tabelle t, (select t.name from irgendeinetabellemitvielensaetzen where rownum <= t.anzahl) ht where t.name = ht.name

ist mit sicherheit nicht schön, nicht performant und ein sql guru findet sicher einen besseren weg.
03.05.2011
nabuchodonossor 1,3k 5
du brauchst auf alle fälle eine hilfstabelle, da gibts in t-sql sicher einen besseren weg als irgendeine tabelle zu nehmen. in oracle z.b. würde ich eine solche tabelle mittels der connect by prior klausel konstruieren.
nabuchodonossor 03.05.2011

Stelle deine Sql-Frage jetzt!