Click here to view and discuss this page in DocCommentXchange. In the future, you will be sent there automatically.

SAP Sybase SQL Anywhere 16.0 (Deutsch) » SQL Anywhere Server - SQL-Benutzerhandbuch » Abfragen und Datenänderung » Allgemeine Tabellenausdrücke

 

Stücklistenproblem

Das Stücklistenproblem ist eine klassische Anwendung einer Rekursion. In diesem Problem werden die Komponenten, die zum Zusammensetzen eines bestimmten Objekts notwendig sind, in einem Graphen dargestellt. Das Ziel ist es, diesen Graphen unter Verwendung einer Datenbanktabelle darzustellen, um dann die Gesamtzahl der notwendigen Elemente zu berechnen.

Der folgende Graph zum Beispiel stellt die Komponenten eines einfachen Bücherregals dar. Das Bücherregal (bookcase) besteht aus drei Fächern (shelves), einer Rückwand (back) und vier Füßen (feet), die mit vier Schrauben (screws) befestigt werden. Jedes Fach ist ein Brett (plank), das mit vier Schrauben befestigt wird. Die Rückwand ist ein weiteres Brett (backboard), das mit acht Schrauben befestigt wird.

Diagramm zur Darstellung hierarchischer Beziehungen von Bücherregal-Unterkomponenten .

Die Angaben in der unten stehenden Tabelle stellen die Ränder des Bücherregalgraphen dar. Die erste Spalte benennt eine Komponente, die zweite Spalte benennt eine der Unterkomponenten dieser Komponente, und die dritte Spalte legt fest, wie viele der Unterkomponenten erforderlich sind.

component subcomponent quantity
bookcase back 1
bookcase side 2
bookcase shelf 3
bookcase foot 4
bookcase screw 4
back backboard 1
back screw 8
side plank 1
shelf plank 1
shelf screw 4

Führen Sie die folgenden Anweisungen aus, um eine Buchregal-Tabelle (bookcase) zu erstellen und Komponenten- und Unterkomponenten-Daten einzufügen.



CREATE TABLE bookcase (
      component      VARCHAR(9),
      subcomponent   VARCHAR(9),
      quantity       INTEGER,
    PRIMARY KEY ( component, subcomponent )
); 
INSERT INTO bookcase
  SELECT 'bookcase', 'back',      1 UNION
  SELECT 'bookcase', 'side',      2 UNION
  SELECT 'bookcase', 'shelf',     3 UNION
  SELECT 'bookcase', 'foot',      4 UNION
  SELECT 'bookcase', 'screw',     4 UNION
  SELECT 'back',     'backboard', 1 UNION
  SELECT 'back',     'screw',     8 UNION
  SELECT 'side',     'plank',     1 UNION
  SELECT 'shelf',    'plank',     1 UNION
  SELECT 'shelf',    'screw',     4;

Führen Sie die folgende Anweisung aus, um eine Liste von Komponenten und Unterkomponenten sowie die Menge zu generieren, die für die Montage des Bücherregals erforderlich ist.

SELECT * FROM bookcase
ORDER BY component, subcomponent;

Führen Sie die folgende Anweisung aus, um eine Liste von Unterkomponenten und die Menge zu generieren, die für die Montage des Bücherregals erforderlich ist.



WITH RECURSIVE parts ( component, subcomponent, quantity ) AS
( SELECT component, subcomponent, quantity
  FROM bookcase WHERE component = 'bookcase'
    UNION ALL
  SELECT b.component, b.subcomponent, p.quantity * b.quantity
  FROM parts p JOIN bookcase b ON p.subcomponent = b.component )
SELECT subcomponent, SUM( quantity ) AS quantity
FROM parts
WHERE subcomponent NOT IN ( SELECT component FROM bookcase )
GROUP BY subcomponent
ORDER BY subcomponent;

Die Ergebnisse dieser Abfrage werden unten angezeigt.

subcomponent quantity
backboard 1
foot 4
plank 5
screw 24

Oder Sie schreiben diese Abfrage um, um eine zusätzliche Stufe der Rekursion durchzuführen und die Unterabfrage in der Haupt-SELECT-Anweisung überflüssig zu machen. Die Ergebnisse der folgenden Abfrage sind mit jenen der vorherigen Abfrage identisch.



WITH RECURSIVE parts ( component, subcomponent, quantity ) AS
( SELECT component, subcomponent, quantity
  FROM bookcase WHERE component = 'bookcase'
    UNION ALL
  SELECT p.subcomponent, b.subcomponent,
    IF b.quantity IS NULL
    THEN p.quantity
    ELSE p.quantity * b.quantity
    ENDIF
  FROM parts p LEFT OUTER JOIN bookcase b
  ON p.subcomponent = b.component
    WHERE p.subcomponent IS NOT NULL
 )
SELECT component, SUM( quantity ) AS quantity
FROM parts
WHERE subcomponent IS NULL
GROUP BY component
ORDER BY component;