2016-05-24 3 views
1

I Tabelle unten habenWie Mindest-Tarif zwischen zwei Städten bekommen

Source Destination Fare 
A   B   10 
B   C   5 
B   D   1 
D   C   1 
A   D   1 

Jetzt habe ich eine Abfrage schreiben wollte, die mir den Mindest-Tarif zwischen zwei Städten geben.

Zum Beispiel, wenn ich will A- gehen> C dann Mindest-Tarif 2 A-> D> C

Was MS-SQL-Abfrage für dieses Problem sein.

+0

Ich bin nicht sicher, dass Sie in der Lage sein werden, Informationen über einzelne SQL-Abfrage –

+1

Sie benötigen ein [** Reiseproblem **] zu erhalten (https://en.wikipedia.org/wiki/Travelling_salesman_problem) -Algorithmus –

+4

Tatsächlich benötigen Sie einen Single-Source-Algorithmus für den kürzesten Pfad, wie den Dijkstra-Algorithmus. Sie würden die Tarife als Kantenwerte verwenden. Der TSP wird nicht funktionieren, da es Ihnen die Route mit den geringsten Kosten geben würde, ALLE Städte zu besuchen, nicht nur die zwei, an denen Sie interessiert sind. – JerryM

Antwort

-3

haben Sie versuchen, Google: SQL Server Handlungsreisende oder SQL Server

Es gibt Unmengen von Antworten kürzesten Weg

+0

Diese Info sollte passen der Kommentarabschnitt schön – JamieD77

+0

Nicht wirklich eine Antwort –

+0

das ist keine Antwort – attaboy182

0

try this:

;WITH Paths AS (
    -- Anchor query: get first step 
    SELECT CAST(CONCAT(Source, '->', Destination) AS VARCHAR(MAX)) AS Path, 
      Destination, Fare, 
      IIF(Destination = 'C', 1, 0) AS Terminate 
    FROM mytable 
    WHERE Source = 'A' 

    UNION ALL 

    -- Recursive part: get next step 
    SELECT CAST(CONCAT(Path, '->', t.Destination) AS VARCHAR(MAX)) AS Path, 
      t.Destination, Fare = t.Fare + p.Fare, 
      IIF(t.Destination = 'C', 1, 0) AS Terminate 
    FROM mytable AS t 
    JOIN Paths AS p ON t.Source = p.Destination 
    WHERE p.Destination <> 'C' 
) 
SELECT Path, Fare 
FROM (
    SELECT Path, Fare, 
     RANK() OVER (ORDER BY Fare) AS rnk 
    FROM Paths 
    WHERE Terminate = 1) AS t 
WHERE t.rnk = 1 

Dies ist eine Art ein Brute-Force-Methode: Sie verwendet einen rekursiven CTE, um alle möglichen Pfade zu erhalten. Dann können wir mit RANK diejenige (n) auswählen, die den Mindestpreis haben.

Demo here

+0

Das ist eine sehr gute Antwort, aber solltest du nicht auch prüfen, ob du die Bedingung auf deiner Ankerabfrage beendest? Wenn Quelle A und Ziel B ist, gibt die aktuelle Abfrage kein Ergebnis zurück. –

+0

@EdmondQuinton Dies wird von der * ersten * Ausführung des rekursiven Teils abgefangen: '... WO p.Ziel <> 'C'' –

+0

Vielleicht fehlt mir etwas. In Ihrer finalen SELECT-Klausel geben Sie nur Zeilen zurück, für die festgestellt wurde, dass der Pfad am Ziel beendet wurde (WHERE Terminate = 1). Wenn jedoch die aktuelle Abfrage geändert wird, um nach dem Mindestfahrpreis von A nach B zu suchen, wäre der einzige verfügbare Weg der direkte Fahrweg von A-> B mit einem Fahrpreis von 10. Da die Ankerabfrage jedoch stets 0 als Abbruch liefert Bedingung und der Pfad A-> B wird nicht in den rekursiven Pfad der Abfrage eingeschlossen, dann wird kein Ergebnis zurückgegeben. –