Heim  >  Artikel  >  php教程  >  Gedanken, die durch eine bestimmte Frage ausgelöst werden

Gedanken, die durch eine bestimmte Frage ausgelöst werden

高洛峰
高洛峰Original
2016-12-13 09:45:311703Durchsuche

Mir wurde heute eine solche Frage gestellt und ich habe sie als Referenz für alle zusammengestellt

Angenommen, es gibt eine Tabelle wie die folgende:

Gedanken, die durch eine bestimmte Frage ausgelöst werden

Hier Daten weist die folgenden Merkmale auf: In einer DepartmentId können mehrere Namen vorhanden sein und umgekehrt. Das heißt, Name und DepartmentId stehen in einer Viele-zu-Viele-Beziehung.

Jetzt möchte ich eine solche Abfrage implementieren: Nach der Sortierung nach DepartmentID (erster Schritt) erhalte ich dann den eindeutigen Wert der Spalte „Name“ (zweiter Schritt) und behalte ihn im ersten Schritt Relative Reihenfolge nach einem Schritt. In diesem Beispiel sind die drei Werte, die zurückgegeben werden sollten: ACB

Wir denken uns zunächst die folgende Schreibmethode aus

wählen Sie einen eindeutigen Namen aus Beispielbestellung nach Abteilungs-ID

Aus semantischer Sicht ist das natürlich. Aber leider kann diese Anweisung überhaupt nicht ausgeführt werden. Die Fehlermeldung lautet:

Gedanken, die durch eine bestimmte Frage ausgelöst werden

Die Bedeutung dieses Fehlers ist, dass bei Verwendung von DISTINCT (Entfernung doppelter Werte) dies der Fall ist erscheint nach OrderBy Das Feld muss auch nach SELECT erscheinen, aber wenn DepartmentID wirklich nach SELECT erscheint, gibt es offensichtlich keine doppelten Werte, sodass das Ergebnis definitiv falsch ist.

Wählen Sie einen eindeutigen Namen, DepartmentId aus der Beispielbestellung nach DepartmentId

Gedanken, die durch eine bestimmte Frage ausgelöst werden

Nun, da die Kombination von DISINCT und OrderBy dieses Problem verursachen wird, ist es so Es ist uns möglich, es zu ändern, zum Beispiel wie folgt:

SELECT eindeutig a.NameFROM (wählen Sie den obersten 100-Prozent-Namen aus Beispielbestellung nach Abteilungs-ID aus) a

Ich möchte vergleichen mit Bei der vorherigen Schreibmethode haben wir die Unterabfragetechnologie verwendet. Auch aus semantischer Sicht ist Still Hot sehr intuitiv und klar. Ich möchte zuerst nach DepartmentId sortieren und dann nach doppelten Werten suchen. Das zurückgegebene Ergebnis lautet jedoch wie folgt:

Gedanken, die durch eine bestimmte Frage ausgelöst werden

Obwohl doppelte Werte tatsächlich entfernt werden, ist die zurückgegebene Reihenfolge falsch. Wir hoffen, zuerst nach DepartmentId zu sortieren, dann doppelte Werte zu entfernen und nach dem Sortieren die relative Reihenfolge beizubehalten.

Warum tritt das obige Ergebnis auf? Tatsächlich liegt es daran, dass DISTINCT selbst die Sortierung durchführt und dieses Verhalten nicht geändert werden kann (dies ist im Ausführungsplan unten zu sehen). Tatsächlich wird der Befehl, den wir zuvor gemacht haben, hier seine Bedeutung verlieren. [Wenn Sie tatsächlich eine ähnliche Abfrage beobachten, die in ORM-Tools wie ADO.NET Entity Framework generiert wird, wird die Einstellung „Reihenfolge nach“ automatisch verworfen]

Gedanken, die durch eine bestimmte Frage ausgelöst werden

Dann so Ist es unter solchen Umständen unmöglich, die Nachfrage zu erfüllen? Obwohl diese Anforderung selten vorkommt, ist DISTINCT in den meisten Fällen die letzte Operation und es ist sinnvoll, eine Sortierung durchzuführen.

Ich habe darüber nachgedacht: Ist es möglich, diesen Vorgang zu umgehen, da das Verhalten von DISTINCT integriert ist? Am Ende lautete eine Lösung, die ich verwendet habe: Kann ich jedem Namen eine Nummer zuweisen? Wenn es beispielsweise zwei A gibt, würde ich das erste A mit 1, das zweite mit A 2 usw. nummerieren. Dann habe ich bei der Abfrage zuerst den Namen mit der Nummer 1 sortiert und dann gefiltert, sodass doppelte Werte tatsächlich entfernt wurden.

SQL Server 2005 begann, eine ROW_NUMBER-Funktion bereitzustellen. In Kombination mit dieser Funktion habe ich die folgende Abfrage implementiert:

wählen Sie einen.Namen aus (wählen Sie die obersten 100 Prozent ausName,Abteilungs-ID,ROW_NUMBER( ) über (Partition nach Name, Reihenfolge nach Abteilungs-ID) rowfrom Beispielbestellung nach Abteilungs-ID) awhere a.row=1order nach a.DepartmentId


Dann habe ich nach Überlegung Folgendes erhalten , ich denke, dieses Ergebnis sollte die zuvor erwähnte Anforderung erfüllen

Gedanken, die durch eine bestimmte Frage ausgelöst werden

Im Vergleich dazu wird die Effizienz dieser Abfrage geringer sein. Dies ist vorhersehbar (Sie können einige Hinweise aus dem sehen Bild unten). Wenn die Anforderungen jedoch streng sind, ist es nicht verwunderlich, dass etwas an Leistung verloren geht. Natürlich können wir weiter studieren, um herauszufinden, ob es bessere Möglichkeiten gibt, es zu schreiben. Unabhängig davon sind Implementierungen mithilfe integrierter Standards in der Regel relativ schnell.

Gedanken, die durch eine bestimmte Frage ausgelöst werden

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Vorheriger Artikel:Oracle-spezifische VerwendungNächster Artikel:Oracle-spezifische Verwendung