2016-10-18 2 views
0

Ich befolge die Übungen in http://www.sql-ex.ru/learn_exercises.php.sql-ex.ru wählen Anweisung Übung 51

In Aufgabe 51 fragen sie: "Finden Sie die Namen der Schiffe mit der größten Anzahl von Geschützen unter allen Schiffen mit der gleichen Verschiebung (einschließlich Schiffe in der Ausgangstabelle)."

Dies ist mein Code, den ersten gesehen db geht, aber nicht passiert den zweiten, unsichtbaren, db (der Fehler - „weniger von 3“):

with t1 as 
(select displacement, max(numguns) 'guns' from classes group by displacement), 
t2 as 
(select class from classes, t1 where classes.displacement = t1.displacement and classes.numguns = t1.guns) 
select name from ships, t2 where ships.class = t2.class 
union 
select ship from outcomes, t2 where outcomes.ship = t2.class 

Die Logik Ich benutze ist, dass die einzige Tabelle in der db, die Verschiebung und Anzahl von Waffen enthält, die Klassen ist, und so t1 und t2 die Klassennamen extrahiert und ich dann einfach die Namen, die zu diesen Klassen gehören, aus der Tabelle ships und ends bekommt.

Kann nicht sehen, warum es einen Fehler geben sollte.

EDIT: ein Scheck für Nullwerte in den Klassen hinzugefügt, und ich erhalte einen neuen Fehler auf dem zweiten unsichtbaren db - „Datenkonflikt (11)“:

with t1 as 
(select displacement, max(numguns) 'guns' from classes group by displacement), 
t2 as 
(select class from classes, t1 where (classes.displacement = t1.displacement or classes.displacement is null) and (classes.numguns = t1.guns or classes.numguns is null)) 
select name from ships, t2 where ships.class = t2.class 
union 
select ship from outcomes, t2 where outcomes.ship = t2.class 

Antwort

1

Wenn Sie in der Datenbank Beschreibung aussehen der relevanten Übung sehen Sie dies:

Schiffe in Klassen haben alle das gleiche allgemeine Design. Eine Klasse ist normalerweise zugewiesen entweder der Name des ersten Schiffes gebaut entsprechend der entsprechenden Design, oder ein Name, der sich von einem beliebigen Schiffsnamen in der Datenbank unterscheidet. Das Schiff, dessen Name einer Klasse zugewiesen ist, heißt ein führendes Schiff.

Das ist bedeutet, dass outcomes Tabelle kann, enthält die Führungsschiff, dessen Name als eine Klasse in der Tabelle classes verwendet wird. Deshalb sollen Sie union die Namen und die Klasse von ship mit dem Namen und den Namen wieder müssen von outcomes aufgrund lead ship gleiche Klasse wie Namen haben.

so können Sie diese Abfrage oder ähnlich mit der gleichen Logik verwenden hinter:

WITH cte 
      AS (SELECT A.name , 
         C.numGuns , 
         C.displacement 
       FROM  (SELECT S.name , 
            S.class 
          FROM  dbo.Ships AS S 
          UNION 
          SELECT O.ship , 
            O.ship 
          FROM  dbo.Outcomes AS O 
         ) AS A 
         JOIN dbo.Classes AS C ON A.class = C.class 
      ) 
    SELECT cte.name 
    FROM cte 
      JOIN (SELECT cte.displacement , 
          MAX(cte.numGuns) AS MaxNumGun 
        FROM  cte 
        GROUP BY cte.displacement 
       ) AS M ON cte.displacement = M.displacement 
          AND cte.numguns = M.MaxNumGun 

Ausgang

enter image description here

+0

das funktioniert. Ich denke, vielleicht müssen Sie die Schiffe und die Ergebnisse verbinden, bevor Sie sich den Klassen anschließen und Verschiebungen und Numguns finden, um auch Namen von Schiffen aus der Ergebnistabelle einzubeziehen, selbst wenn sie keine Werte in Klassen haben. d. h. nach dem Verbinden mit den Klassen sind ihre Werte für Verschiebung und Anzahl an Nullen "Null". Hab ich recht? –

+0

@DavidRefaeli gibt es eine andere Logik dahinter, siehe Erklärung in meinem aktualisierten Beitrag – Vasily