2016-11-13 4 views
0
beitreten Verwendung links

Angenommen, Sie eine Tabelle wie folgt aus:Doppelte Zeilen

+----+--------+-------------+----------------+--------+ 
| Id | Parent | Description | NumberOfThings | Number | 
+----+--------+-------------+----------------+--------+ 
| A | NULL | This is A |    1 | NULL | 
| B | NULL | This is B |    3 | NULL | 
| C | NULL | This is C |    2 | NULL | 
+----+--------+-------------+----------------+--------+ 

und Sie die NumberOfThings verwenden möchten X Kinder Reihe von Dingen erstellen:

+-----+--------+-------------+----------------+--------+ 
| Id | Parent | Description | NumberOfThings | Number | 
+-----+--------+-------------+----------------+--------+ 
| A | NULL | This is A |    1 | NULL | 
| B | NULL | This is B |    3 | NULL | 
| C | NULL | This is C |    2 | NULL | 
| A-1 | A  | This is A |    1 | 1  | 
| B-1 | B  | This is B |    1 | 1  | 
| C-1 | C  | This is C |    1 | 1  | 
| B-2 | B  | This is B |    1 | 2  | 
| C-2 | C  | This is C |    1 | 2  | 
| B-3 | B  | This is B |    1 | 3  | 
+-----+--------+-------------+----------------+--------+ 

Wie würde ich mich über Dies tun? Ich habe eine Idee, dass ich einen LEFT JOIN und vielleicht eine Wildcard ON-Klausel verwenden könnte, aber ich bin nicht sicher, wo ich damit anfangen soll.

Dies verwendet SQL Server 2012, aber ich glaube, dass es eine Lösung geben kann, die nicht für jede DB-Engine spezifisch ist.

SQL Fiddle mit ersten Versuch: http://sqlfiddle.com/#!6/dcafc/2

+2

Sie müssen sich an eine Numbers-Tabelle einer Art anmelden, wobei der Join mit jedem Datensatz in der Numbers-Tabelle <= der 'NumberOfThings'-Spalte übereinstimmt. Dies wird helfen: http://stackoverflow.com/questions/1393951/what-is-the-best-way-to-create-and-populate-a-number-table –

Antwort

0

Es ist ein bisschen chaotisch, aber eine rekursive CTE kann dies tun:

with cte as (
    select Id as BaseId, 
     cast(Id as varchar(10)) as Id, 
     cast(null as varchar(1)) as Parent, 
     Description, 
     NumberOfThings, 
     NumberOfThings as TotalCount, 
     1 as CurrentCount, 
     null as Number 
    from NumThings 
    union all 
    select c.BaseId, 
     cast(c.BaseId + '-' + cast(c.CurrentCount as varchar(8)) as varchar(10)) as Id, 
     c.BaseId as Parent, 
     c.Description, 
     1 as NumberOfThings, 
     c.TotalCount, 
     c.CurrentCount + 1 as CurrentCount, 
     c.CurrentCount as Number 
    from cte c 
    where c.CurrentCount <= c.TotalCount 
) 
select Id, 
     Parent, 
     Description, 
     NumberOfThings, 
     Number 
    from cte 
order by case when Parent is null then 0 else 1 end, 
      Number, 
      Id; 

Demo.

0

Es scheint, wie Sie sich für die Vereinigung der Menge und dem Kreuzprodukt des Satzes mit sich selbst suchen. Allerdings bin ich mir nicht sicher, ob dies richtig ist, wenn man das gewünschte Ergebnis für die NumberOfThings-Spalte erwartet.

SELECT 
    [Id] 
    , [Parent] 
    , [NumberOfThings] 
FROM 
    [dbo].[NumThings] 
UNION ALL 
SELECT 
    A.[Id] + '-' + CAST(B.NumberOfThings AS VARCHAR(50)) 
    , B.[Id] As Parent 
    , A.[NumberOfThings] 
FROM 
    [dbo].[NumThings] A 
    , [dbo].[NumThings] B 
GO 
+0

Das ist nicht ganz das, was ich wollte: http://sqlfiddle.com/#!6/dcafc/2 Wie Sie sehen können, hat es 3 Kind A's erstellt, als es nur 1 – ParoX

0

hier ..... Ich glaube, dies ist das Ergebnis der Sie suchen:

 SELECT 
     [Id] 
      , [Parent] 
      , [NumberOfThings] 
     FROM 
[dbo].[NumThings] 
     UNION ALL 
    SELECT 
      A.[Id] + '-' + CAST(B.NumberOfThings AS VARCHAR(50)) 
      , A.[Id] As Parent 
     , B.[NumberOfThings] 
    FROM 
     [dbo].[NumThings] A 
    LEFT JOIN [dbo].[NumThings] B 
     ON B.NumberOfThings BETWEEN 1 AND A.NumberOfThings 
    GO 
+0

Nice One benötigt. Leider wird es nicht funktionieren, wenn Sie zum Beispiel den Wert von 'NumberOfThings' in einer der Zeilen auf' 10' setzen. – sstan

+0

Mein Missverständnis dann, als ich dachte "NumberOfThings" war etwas mit der Anzahl der "Sache" in Ihrer Tabelle verbunden .... ie. 10 Dinge würden A-J erfordern ...... wenn das nicht der Fall ist, dann glaube ich nicht, dass Cross-Joining-Tische wirklich einen Zweck erfüllen – user3289372