SELECT DISTINCT für eine Spalte, während die anderen Spalten zurückgegeben werden?

12

Ich habe eine Abfrage, die drei Nachschlagetabellen verwendet, um alle benötigten Informationen abzurufen. Ich brauche DISTINCTWerte für eine Spalte, aber ich brauche auch den Rest der damit verbundenen Daten.

Mein SQL Code:

SELECT acss_lookup.ID AS acss_lookupID,
   acss_lookup.product_lookupID AS acssproduct_lookupID,
   acss_lookup.region_lookupID AS acssregion_lookupID,
   acss_lookup.document_lookupID AS acssdocument_lookupID,
   product.ID AS product_ID,
   product.parent_productID AS productparent_product_ID,
   product.label AS product_label,
   product.displayheading AS product_displayheading,
   product.displayorder AS product_displayorder,
   product.display AS product_display,
   product.ignorenewupdate AS product_ignorenewupdate,
   product.directlink AS product_directlink,
   product.directlinkURL AS product_directlinkURL,
   product.shortdescription AS product_shortdescription,
   product.logo AS product_logo,
   product.thumbnail AS product_thumbnail,
   product.content AS product_content,
   product.pdf AS product_pdf,
   product.language_lookupID AS product_language_lookupID,
   document.ID AS document_ID,
   document.shortdescription AS document_shortdescription,
   document.language_lookupID AS document_language_lookupID,
   document.document_note AS document_document_note,
   document.displayheading AS document_displayheading
FROM acss_lookup
     INNER JOIN product ON (acss_lookup.product_lookupID = product.ID)
     INNER JOIN document ON (acss_lookup.document_lookupID = document.ID)
ORDER BY product_displayheading ASC;

Ich möchte alle Produkte aus dieser Abfrage abrufen, möchte sie jedoch nur einmal abrufen, da ich ein Dropdown-Menü für eine Suchanwendung ausfülle. Ich möchte, dass der Benutzer aus den in dieser Tabelle aufgeführten Produkten auswählen kann (daher benötige ich sie nur einmal).

Ist das zu kompliziert? Sollte ich einen vereinfachten Ansatz verwenden?

stephmoreland
quelle
Aber ein Produkt hat mit vielen Dokumenten zu tun. Und Ihre Abfrage gibt sie alle zurück (Dokumente für ein Produkt). Welches sollte gewählt werden?
ypercubeᵀᴹ

Antworten:

6

Ein weiterer Ansatz, der noch nicht erwähnt wurde, ist die Verwendung von Fensterfunktionen, zum Beispiel row_number:

   SELECT * FROM  
   (
   SELECT acss_lookup.ID AS acss_lookupID, 
   ROW_NUMBER() OVER 
   (PARTITION BY your_distinct_column ORDER BY any_column_you_think_is_appropriate)
   as num,
   acss_lookup.product_lookupID AS acssproduct_lookupID,
   acss_lookup.region_lookupID AS acssregion_lookupID,
   acss_lookup.document_lookupID AS acssdocument_lookupID,
   product.ID AS product_ID,
   product.parent_productID AS productparent_product_ID,
   product.label AS product_label,
   product.displayheading AS product_displayheading,
   product.displayorder AS product_displayorder,
   product.display AS product_display,
   product.ignorenewupdate AS product_ignorenewupdate,
   product.directlink AS product_directlink,
   product.directlinkURL AS product_directlinkURL,
   product.shortdescription AS product_shortdescription,
   product.logo AS product_logo,
   product.thumbnail AS product_thumbnail,
   product.content AS product_content,
   product.pdf AS product_pdf,
   product.language_lookupID AS product_language_lookupID,
   document.ID AS document_ID,
   document.shortdescription AS document_shortdescription,
   document.language_lookupID AS document_language_lookupID,
   document.document_note AS document_document_note,
   document.displayheading AS document_displayheading
   FROM acss_lookup
     INNER JOIN product ON (acss_lookup.product_lookupID = product.ID)
     INNER JOIN document ON (acss_lookup.document_lookupID = document.ID)
   )a
   WHERE a.num = 1
   ORDER BY product_displayheading ASC;
a1ex07
quelle
@ a1ex07- Danke! Das hat funktioniert. Jedes Mal, wenn ich versuchte, ein Beispiel aus dem Netz zu adaptieren, waren es meine JOINS, die mich verwirrten, aber ich glaube, ich verstehe es jetzt.
stephmoreland
Es wäre besser, die Verknüpfungen außerhalb der Unterabfrage auszuführen, wenn die Daten dadurch nicht "unterschieden" würden, um die Daten, die Sie abfragen und duplizieren, zu minimieren und nur durch Auswahl von num = 1 aus der Fensterfunktion "wegzuwerfen".
Allan S. Hansen
4

Hierfür gibt es verschiedene Möglichkeiten. Die beiden wichtigsten, die ich verwende, sind allgemeine Tabellenausdrücke und Unterabfragen. Unter Verwendung eines CTE würde Ihre Anfrage ungefähr so ​​aussehen:

WITH theResultSet AS
(
    SELECT DISTINCT(column) AS col1 FROM some.table
)
SELECT whatever
  FROM more.data AS a
  JOIN theResultSet as b ON a.col1 = b.col1
  /* additional joins, clauses etc...*/

Oder mit einer Unterabfrage:

SELECT whatever
  FROM more.data AS a
  JOIN (SELECT DISTINCT(column) AS col1 FROM some.table) AS b ON a.col1 = b.col1
/* additional joins, clauses etc... */

Normalerweise teste ich, was schneller ist und gehe damit um.

Ich hoffe das hilft dir.

Herr Brownstone
quelle
Ich dachte, ich hätte Ihre Antwort verstanden, also habe ich es versucht (die erste), aber ich denke, meine JOINS verursachen ein Problem mit den JOINS Ihrer Lösung.
stephmoreland
Was ist die Spalte, die unterschieden werden muss? Ich werde eine umfassendere Lösung für Sie posten.
Mr. Brownstone
product.displayheading ist die Spalte
stephmoreland
1

(Ich denke, Sie versuchen, jede Ergebniszeile auf ein einzelnes Produkt zu reduzieren. Diese Antwort geht also von dieser Annahme aus.)

Das ist nicht möglich. Um die zugehörigen 1 .. * -Daten aus den anderen Tabellen abzurufen, müssen Sie doppelte Werte in den anderen Spalten zurückgeben.

Im Allgemeinen können Sie die Abfrage so ausführen, wie sie ist, und die verknüpfte Ergebnismenge im Anwendungscode verarbeiten. Normalerweise verwende ich dazu einen Hash-Erfassungsansatz, bei dem unterschiedliche Entitäten jedes Typs in einer Sammlung basierend auf einem Schlüsselwert gefunden werden.

Dieser Ansatz kostet zwar mehr Netzwerkverkehr, ist jedoch in der Regel besser geeignet, mehrere Abfragen auszuführen und die Ergebnisse nach Bedarf im Anwendungscode zusammenzufügen. Dies hängt von vielen Faktoren ab, einschließlich der Häufigkeit der Ausführung der Abfragen und der Anzahl der zurückgegebenen Daten.

Jon Seigel
quelle