Zählen Sie die Anzahl der Datensätze in Gruppen (erstellt durch GROUP BY). Auswählen und Zählen von Zeilen in einer Abfrage – SQL_CALC_FOUND_ROWS SQL-Zählmenge

SQL – Lektion 8. Datensätze gruppieren und die Funktion COUNT()

Erinnern wir uns daran, welche Botschaften und zu welchen Themen wir haben. Dazu können Sie die übliche Abfrage verwenden:

Was wäre, wenn wir nur herausfinden müssten, wie viele Nachrichten es im Forum gibt? Dazu können Sie die integrierte Funktion nutzen ZÄHLEN(). Diese Funktion zählt die Anzahl der Zeilen. Wenn außerdem * als Argument für diese Funktion verwendet wird, werden alle Zeilen der Tabelle gezählt. Und wenn ein Spaltenname als Argument angegeben wird, werden nur die Zeilen gezählt, die einen Wert in der angegebenen Spalte haben.

In unserem Beispiel liefern beide Argumente das gleiche Ergebnis, weil Alle Tabellenspalten sind NICHT NULL. Schreiben wir eine Abfrage mit der Spalte id_topic als Argument:

SELECT COUNT(id_topic) FROM posts;

Es gibt also 4 Nachrichten in unseren Themen. Was aber, wenn wir wissen möchten, wie viele Beiträge es zu jedem Thema gibt? Dazu müssen wir unsere Nachrichten nach Themen gruppieren und die Anzahl der Nachrichten für jede Gruppe berechnen. Verwenden Sie zum Gruppieren in SQL den Operator GRUPPE NACH. Unsere Anfrage wird nun so aussehen:

SELECT id_topic, COUNT(id_topic) FROM posts GROUP BY id_topic;

Operator GRUPPE NACH weist das DBMS an, die Daten nach der Spalte „id_topic“ zu gruppieren (d. h. jedes Thema ist eine separate Gruppe) und die Anzahl der Zeilen für jede Gruppe zu zählen:

Nun, im Thema mit der ID=1 haben wir 3 Nachrichten und mit der ID=4 eine. Wären übrigens fehlende Werte im Feld id_topic möglich, dann würden solche Zeilen zu einer separaten Gruppe mit dem Wert NULL zusammengefasst.

Nehmen wir an, dass uns nur die Gruppen interessieren, die mehr als zwei Nachrichten haben. In einer normalen Abfrage würden wir die Bedingung mithilfe des Operators angeben WO, aber dieser Operator kann nur mit Zeichenfolgen arbeiten und für Gruppen werden dieselben Funktionen vom Operator ausgeführt HABEN:

SELECT id_topic, COUNT(id_topic) FROM posts GROUP BY id_topic HAVING COUNT(id_topic) > 2;

Als Ergebnis haben wir:

In Lektion 4 haben wir uns angeschaut, welche Bedingungen vom Betreiber eingestellt werden können WO, können die gleichen Bedingungen vom Betreiber eingestellt werden HABEN, das musst du dir nur merken WO Filtert Zeichenfolgen und HABEN- Gruppen.

Heute haben wir gelernt, wie man Gruppen erstellt und wie man die Anzahl der Zeilen in einer Tabelle und in Gruppen zählt. Im Allgemeinen zusammen mit dem Betreiber GRUPPE NACH Sie können andere integrierte Funktionen verwenden, wir werden sie jedoch später untersuchen.

Wie kann ich herausfinden, wie viele PC-Modelle ein bestimmter Anbieter produziert? So ermitteln Sie den Durchschnittspreis von Computern mit demselben Preis technische Spezifikationen? Diese und viele andere Fragen im Zusammenhang mit einigen statistischen Informationen können mit beantwortet werden endgültige (Aggregat-)Funktionen. Der Standard stellt die folgenden Aggregatfunktionen bereit:

Alle diese Funktionen geben einen einzelnen Wert zurück. Gleichzeitig sind die Funktionen ZÄHLUNG, MIN Und MAX anwendbar auf jeden Datentyp, während SUMME Und Durchschnittlich werden nur für numerische Felder verwendet. Unterschied zwischen Funktion ZÄHLEN(*) Und ZÄHLEN(<имя поля>) ist, dass der zweite bei der Berechnung keine NULL-Werte berücksichtigt.

Beispiel. Finden Sie den Mindest- und Höchstpreis für Personalcomputer:

Beispiel. Finden Sie die verfügbare Anzahl von Computern des Herstellers A:

Beispiel. Wenn uns die Menge interessiert verschiedene Modelle, produziert von Hersteller A, dann lässt sich die Abfrage wie folgt formulieren (unter Ausnutzung der Tatsache, dass in der Produkttabelle jedes Modell einmal erfasst wird):

Beispiel. Finden Sie die Anzahl der verfügbaren verschiedenen Modelle des Herstellers A. Die Abfrage ähnelt der vorherigen, bei der ermittelt werden musste Gesamtzahl Modelle des Herstellers A. Hier müssen Sie auch die Anzahl der verschiedenen Modelle in der PC-Tabelle ermitteln (d. h. im Handel erhältlich).

Um sicherzustellen, dass beim Erhalten statistischer Indikatoren nur eindeutige Werte verwendet werden, wann Argument von Aggregatfunktionen verwendet werden kann DISTINCT-Parameter. Ein anderer Parameter ALLE ist die Standardeinstellung und geht davon aus, dass alle zurückgegebenen Werte in der Spalte gezählt werden. Operator,

Wenn wir die Anzahl der produzierten PC-Modelle benötigen alle Hersteller, den Sie verwenden müssen GROUP BY-Klausel, syntaktisch folgend WHERE-Klauseln.

GROUP BY-Klausel

GROUP BY-Klausel Wird verwendet, um Gruppen von Ausgabezeichenfolgen zu definieren, auf die angewendet werden kann Aggregatfunktionen (COUNT, MIN, MAX, AVG und SUM). Wenn diese Klausel fehlt und Aggregatfunktionen verwendet werden, dann werden alle Spalten mit den in genannten Namen verwendet WÄHLEN, sollte darin enthalten sein Aggregatfunktionen, und diese Funktionen werden auf den gesamten Satz von Zeilen angewendet, die das Abfrageprädikat erfüllen. Ansonsten alle Spalten der SELECT-Liste nicht enthalten in Aggregatfunktionen müssen angegeben werden in der GROUP BY-Klausel. Dadurch werden alle Ausgabeabfragezeilen in Gruppen unterteilt, die durch die gleichen Wertekombinationen in diesen Spalten gekennzeichnet sind. Danach werden Aggregatfunktionen auf jede Gruppe angewendet. Denken Sie daran, dass für GROUP BY alles gilt NULL-Werte
werden gleich behandelt, d.h. Bei der Gruppierung nach einem Feld mit NULL-Werten fallen alle Zeilen in eine Gruppe. Wenn wenn es eine GROUP BY-Klausel gibt , in der SELECT-Klausel keine Aggregatfunktionen
, dann gibt die Abfrage einfach eine Zeile aus jeder Gruppe zurück. Diese Funktion kann zusammen mit dem Schlüsselwort DISTINCT verwendet werden, um doppelte Zeilen in einer Ergebnismenge zu entfernen.
Schauen wir uns ein einfaches Beispiel an:
SELECT model, COUNT(model) AS Qty_model, AVG(price) AS Avg_price
VOM PC

GROUP BY-Modell; In dieser Anfrage werden für jedes PC-Modell deren Anzahl und durchschnittliche Kosten ermittelt. Alle Zeilen mit die gleichen Werte
Modell (Modellnummer) bilden eine Gruppe, und der SELECT-Ausgang berechnet die Anzahl der Werte und Durchschnittspreiswerte für jede Gruppe. Das Ergebnis der Abfrage ist die folgende Tabelle: Modell Mengenmodell
1121 3 850.0
1232 4 425.0
1233 3 843.33333333333337
1260 1 350.0

Durchschn. Preis

Wenn SELECT eine Datumsspalte hätte, wäre es möglich, diese Indikatoren für jedes bestimmte Datum zu berechnen. Dazu müssen Sie das Datum als Gruppierungsspalte hinzufügen und dann werden die Aggregatfunktionen für jede Wertekombination (Modelldatum) berechnet. Es gibt mehrere spezifische:

  • Regeln für die Ausführung von Aggregatfunktionen Wenn als Ergebnis der Anfrage Es wurden keine Zeilen empfangen
  • (oder mehr als eine Zeile für eine bestimmte Gruppe), dann gibt es keine Quelldaten für die Berechnung einer der Aggregatfunktionen. In diesem Fall ist das Ergebnis der COUNT-Funktionen Null und das Ergebnis aller anderen Funktionen ist NULL. Argument Aggregatfunktion kann selbst keine Aggregatfunktionen enthalten
  • (Funktion aus Funktion). Diese. In einer Abfrage ist es beispielsweise unmöglich, das Maximum an Durchschnittswerten zu erhalten. Das Ergebnis der Ausführung der COUNT-Funktion ist ganze Zahl
  • (GANZE ZAHL). Andere Aggregatfunktionen erben die Datentypen der von ihnen verarbeiteten Werte. Wenn bei der Ausführung SUMME-Funktionen Überschreitet ein Ergebnis den Maximalwert des verwendeten Datentyps, kommt es zu einem Ergebnis.

Fehler Also, wenn die Anfrage nicht enthält GROUP BY-Klauseln Aggregatfunktionen, Das enthalten SELECT-Klausel GROUP BY-Klausel, jeder Satz von Zeilen, der die gleichen Werte einer in angegebenen Spalte oder Spaltengruppe hat GROUP BY-Klausel, bildet eine Gruppe und Aggregatfunktionen werden für jede Gruppe separat durchgeführt.

HABEN Angebot

werden gleich behandelt, d.h. Bei der Gruppierung nach einem Feld mit NULL-Werten fallen alle Zeilen in eine Gruppe. WHERE-Klausel definiert dann ein Prädikat zum Filtern von Zeilen HABEN Angebot gilt nach der Gruppierung um ein ähnliches Prädikat zu definieren, das Gruppen nach Werten filtert Aggregatfunktionen. Diese Klausel wird benötigt, um die Werte zu validieren, die mit erhalten werden Aggregatfunktion nicht aus einzelnen Zeilen der in definierten Datensatzquelle FROM-Klausel, und von Gruppen solcher Linien. Daher kann eine solche Prüfung nicht darin enthalten sein WHERE-Klausel.

Dabei Lehrbuch Sie werden lernen, wie man es benutzt COUNT-Funktion V SQL-Server(Transact-SQL) mit Syntax und Beispielen.

Beschreibung

In SQL Server (Transact-SQL) COUNT-Funktion gibt die Anzahl der Zeilen eines Feldes oder Ausdrucks im Ergebnissatz zurück.

Syntax

Die Syntax für die COUNT-Funktion in SQL Server (Transact-SQL) lautet:

ODER die Syntax für die COUNT-Funktion beim Gruppieren der Ergebnisse einer oder mehrerer Spalten lautet:

Parameter oder Argumente

Ausdruck1, Ausdruck2, … Ausdruck_n
Ausdrücke, die nicht in einer COUNT-Funktion eingeschlossen sind und in einer GROUP BY-Klausel am Ende der SQL-Anweisung enthalten sein müssen.
aggregat_expression ist die Spalte oder der Ausdruck, deren Nicht-NULL-Werte gezählt werden.
Tabellen – Tabellen, aus denen Sie Datensätze abrufen möchten. In der FROM-Klausel muss mindestens eine Tabelle aufgeführt sein.
WHERE-Bedingungen – optional. Dies sind die Bedingungen, die für die ausgewählten Datensätze erfüllt sein müssen.

Einschließlich Nicht-NULL-Werte

Nicht jeder versteht das, aber die COUNT-Funktion zählt nur die Datensätze, bei denen der Wert des Ausdrucks in COUNT (aggregate_expression) nicht NULL ist. Wenn ein Ausdruck einen NULL-Wert enthält, wird er nicht im COUNT-Zähler berücksichtigt.

Schauen wir uns ein Beispiel der COUNT-Funktion an, das zeigt, wie NULL-Werte von der COUNT-Funktion ausgewertet werden.

Wenn Sie beispielsweise die folgende Tabelle mit dem Namen „Märkte“ haben:

Das Beispiel COUNT gibt 3 zurück, da alle Market_id-Werte im Abfrageergebnissatz NICHT NULL sind.

Wenn Sie jedoch Folgendes ausgeführt haben SELECT-Anweisung welches die COUNT-Funktion verwendet:

Transact-SQL

Wählen Sie die Anzahl (Mitglieder) aus den Märkten aus. --Ergebnis: 1

Dieses COUNT-Beispiel gibt nur 1 zurück, da nur ein Filialwert im Abfrageergebnissatz NICHT NULL ist. Dies ist die erste Zeile mit der Aufschrift filials = „yes“. Dies ist die einzige Zeile, die in die Berechnung der COUNT-Funktion einbezogen wird.

Anwendung

Die COUNT-Funktion kann im Folgenden verwendet werden SQL-Versionen Server (Transact-SQL):
SQL Server vNext, SQL Server 2016, SQL Server 2015, SQL Server 2014, SQL Server 2012, SQL Server 2008 R2, SQL Server 2008, SQL Server 2005

Beispiel mit einem Feld

Schauen wir uns einige an SQL-Beispiele Server-COUNT-Funktionen, um zu verstehen, wie die COUNT-Funktion in SQL Server (Transact-SQL) verwendet wird.

So können Sie beispielsweise herausfinden, wie viele Kontakte ein Benutzer mit last_name = „Rasputin“ hat.

In diesem Beispiel der COUNT-Funktion haben wir den Alias ​​„Anzahl der Kontakte“ für den COUNT (*)-Ausdruck angegeben. Daher wird in der Ergebnismenge „Anzahl der Kontakte“ als Feldname angezeigt.

Beispiel mit DISTINCT

Sie können den DISTINCT-Operator in der COUNT-Funktion verwenden. Die folgende SQL-Anweisung gibt beispielsweise die Anzahl der eindeutigen Abteilungen zurück, in denen mindestens ein Mitarbeiter den Vornamen = „Samvel“ hat.

Ich habe eine Anfrage wie:

SELECT i.*, COUNT(*) AS-Währungen, SUM(ig.quantity) AS total, SUM(g.price * ig.quantity) AS-Preis, c.kurz AS cname FROM bill AS i, bill_goods AS ig, good g LEFT JOIN Währung c ON (c.id = g.currency) WHERE ig.invoice_id = i.id AND g.id = ig.good_id GROUP BY g.currency ORDER BY i.date DESC;

diese. Es wird eine Liste von Bestellungen ausgewählt, in der die Gesamtkosten der Waren in verschiedenen Währungen berechnet werden (die Währung ist für das Produkt festgelegt, die Spalte cname im Ergebnis ist der Name der Währung).

Sie müssen die Anzahl der Datensätze mit derselben i.id in der Währungsergebnisspalte ermitteln. Experimente mit den COUNT()-Parametern haben jedoch zu nichts geführt – es wird immer 1 zurückgegeben

Frage: Ist es möglich, den wahren Wert in der Währungsspalte zu ermitteln? Diese. Wenn Waren mit Preisen in 3 verschiedenen Währungen bestellt werden, Währungen=3 ?

Allerdings lässt sich MySQL in Bezug auf SQL zu viele Freiheiten. Was bedeutet zum Beispiel i.* im Kontext dieser Auswahl? Alle Spalten der Rechnungstabelle? Da für sie keine Gruppierungsfunktion gilt, wäre es schön, wenn sie in GROUP BY aufgeführt würden, da sonst das Prinzip der Gruppierung von Zeilen nicht ganz klar ist. Wenn Sie alle Waren für alle Bestellungen nach Währung erhalten müssen, ist das eine Sache. Wenn Sie alle Waren für jede Bestellung nach Währung gruppiert erhalten müssen, ist das eine völlig andere Sache.
Basierend auf Ihrer Auswahl können wir von der folgenden Datenstruktur ausgehen:
Rechnungstabelle:

Tabelle „Invoice_goods“:

Warentisch:

Währungstabelle:

Was wird Ihre aktuelle Auswahl zurückgeben? Theoretisch werden für jede Bestellung und jede Währung, in der diese Bestellung Waren enthält, N-Zeilen zurückgegeben. Aufgrund der Tatsache, dass in group by jedoch nichts anderes als g.currency angegeben ist, ist dies nicht offensichtlich :) Darüber hinaus trägt die c.briefly-Spalte auch zur impliziten Bildung von Gruppen bei. Als Ergebnis erhalten wir für jede eindeutige Kombination von i.*, g.currency und c.briefly eine Gruppe, auf deren Zeilen die Funktionen SUM und COUNT angewendet werden. Die Tatsache, dass Sie beim Herumspielen mit dem COUNT-Parameter immer 1 erhalten haben, bedeutet, dass es in der resultierenden Gruppe nur einen Datensatz gab (d. h. die Gruppen wurden nicht wie gewünscht gebildet. Können Sie die Anforderungen genauer beschreiben?). Aus Ihrer Frage geht nicht klar hervor, was Sie wissen möchten: Wie viele verschiedene Währungen waren an der Bestellung beteiligt oder wie viele Bestellungen waren in einer bestimmten Währung? Im ersten Fall sind mehrere Optionen möglich, alles hängt von den Fähigkeiten von MySQL ab; im zweiten Fall müssen Sie den Auswahlausdruck anders schreiben.

Allerdings lässt sich MySQL in Bezug auf SQL zu viele Freiheiten. Was bedeutet zum Beispiel i.* im Kontext dieser Auswahl? Alle Spalten der Rechnungstabelle?

Ja, genau. Das spielt aber keine große Rolle, denn... In diesem Fall sind darunter keine sinnvollen Spalten. Sei i.* i.id . Um genau zu sein.

Was wird Ihre aktuelle Auswahl zurückgeben? Theoretisch werden für jede Bestellung und jede Währung, in der diese Bestellung Waren enthält, N-Zeilen zurückgegeben. Aber aufgrund der Tatsache, dass „group by“ nichts anderes als „g.currency“ angibt, ist dies nicht offensichtlich :),

Das ist richtig.
Es wird Folgendes zurückgegeben (in diesem Beispiel wähle ich aus i nur id und nicht alle Spalten aus):

AusweisWährungengesamtPreiscname
33 1 1.00 198.00 B.F.
33 1 4.00 1548.04 REIBEN
Darüber hinaus trägt die c.briefly-Spalte auch zur impliziten Gruppenbildung bei.

Wie? Tabellen werden durch c.id=g.currency verbunden und nach g.currency gruppiert.

Die Tatsache, dass Sie beim Spielen mit dem COUNT-Parameter immer 1 erhalten haben, bedeutet, dass es in der resultierenden Gruppe nur einen Datensatz gab

Nein, die Gruppe wurde daraus aufgebaut 1 Aufzeichnungen. Soweit ich das verstehe, gibt COUNT() aus diesem Grund 1 zurück (schließlich werden die in der Gruppe unterschiedlichen Spalten (allerdings mit Ausnahme der Währungsspalte) durch Aggregatfunktionen erstellt).

(d. h. die Gruppen werden nicht so gebildet, wie Sie es möglicherweise benötigen. Können Sie die Anforderungen genauer beschreiben?).

Gruppen werden nach Bedarf gebildet, jede Gruppe -- Das Gesamtkosten der Waren in jeder Währung. Abgesehen davon habe ich jedoch Ich muss berechnen, wie viel Dasselbe Elemente in Das Gruppe.

Aus Ihrer Frage geht nicht klar hervor, was Sie wissen möchten: Wie viele verschiedene Währungen waren an der Bestellung beteiligt oder wie viele Bestellungen waren in einer bestimmten Währung?

Ja, ich habe ein bisschen Geld verdient. Nur das erste.

dmig[Dossier]
Mit „impliziter“ Teilnahme an der Bildung einer Gruppe meine ich, dass das Ergebnis der Auswahl identisch ist, wenn die Spalte nicht in GROUP BY angegeben ist und gleichzeitig KEIN Argument für die Gruppenfunktion ist Was wäre, wenn diese Spalte in GROUP BY angegeben WÄRE. Ihre Auswahl und die Auswahl unten führen zu genau demselben Ergebnis (achten Sie nicht auf die Verknüpfungen, ich habe sie nur in ein einziges Aufnahmeformat gebracht):

Wählen Sie i.id id, count(*) Währungen, sum(ig.quantity) total, SUM(g.price * ig.quantity) Preis, c.kurz cname FROM Rechnung aus, ich schließe Rechnung_Waren an (ig.invoice_id = i. id) beitreten gut g on (g.id = ig.good_id) LEFT OUTER JOIN Währung c ON (c.id = g.currency) gruppieren nach i.id, c.briefly

Es stellt sich heraus, dass es in jeder Zeile der resultierenden Stichprobe eine und nur eine Währung gibt (wäre sie unterschiedlich, gäbe es zwei Zeilen). Von wie vielen Elementen reden wir in diesem Fall? Über Bestellartikel? Dann ist Ihre Auswahl absolut richtig, nur für diese Währung gibt es in dieser Bestellung nur einen Artikel.
Schauen wir uns das Datenschema an:

  1. Es gibt viele Artikel (Zeilen) in einer Bestellung, oder?
  2. Jeder Artikel ist ein Produkt im Warenverzeichnis, oder?
  3. Jedes Produkt hat eine bestimmte (und nur eine) Währung, das ergibt sich aus c.id = g.currency, oder?

Wie viele Währungen sind in der Bestellung enthalten? Darin sind ebenso viele Punkte mit VERSCHIEDENEN Währungen enthalten.
Das Addieren von g.price * ig.quantity macht nur für Punkte in einer Währung Sinn ;) (obwohl auch Kilometer mit Stunden addiert werden können :) Was passt also nicht zu Ihnen!? Sie geben an, dass Sie benötigen, wie viele verschiedene Währungen an der Bestellung beteiligt waren
und in diesem Fall wird es nicht funktionieren, dies im Rahmen derselben Auswahl ohne alle möglichen Tricks zu tun (was MySQL höchstwahrscheinlich nicht tun wird);(
Leider bin ich kein MySQL-Experte. In Oracle können Sie dies mit einem Select tun, aber hilft Ihnen dieser Rat? Kaum ;)

# Es gibt viele Artikel (Zeilen) in einer Bestellung, oder?
# Jeder Artikel ist ein Produkt im Warenverzeichnis, oder?
# Jedes Produkt hat eine bestimmte (und nur eine) Währung, das ergibt sich aus c.id = g.currency, oder?

Also.
Eine Bestellung: ein Datensatz in der Rechnungstabelle, er entspricht n(>0) Datensätzen in bill_goods, von denen jeder einem Datensatz in der Warentabelle entspricht, der Datensatz „Währung“ in jedem von ihnen entspricht wiederum dem 1. Datensatz in der Währungstabelle (LEFT JOIN – im Falle der Bearbeitung des Währungsverzeichnisses mit krummen Händen – Tabellen wie MyISAM unterstützen keine Fremdschlüssel).

Wie viele Währungen sind in der Bestellung enthalten? Darin sind ebenso viele Punkte mit VERSCHIEDENEN Währungen enthalten.

Ja, das stimmt.

Das Hinzufügen von g.price * ig.quantity ist nur für Punkte in einer Währung sinnvoll;) (obwohl auch Kilometer mit Stunden hinzugefügt werden können :)

Aus diesem Grund erfolgt die Gruppierung nach Währungs-ID (g.currency).

In Oracle können Sie dies mit einem Select tun, aber hilft Ihnen dieser Rat?

M.b.
Ich habe ein wenig mit Oracle gesprochen und bin mit pl/sql vertraut.

Option Nr. 1.

Wählen Sie a.*, count(*) über (partitionieren Sie durch a.id) Währungen aus (select i.id id, sum(ig.quantity) total, SUM(g.price * ig.quantity) price, c.shortly cname FROM Rechnung verbinde ich Rechnung_Waren ig auf (ig.invoice_id = i.id) verbinde Ware g auf (g.id = ig.good_id) LEFT OUTER JOIN Währung c ON (c.id = g.Währung) gruppieren nach i.id, c.kurz)a

Dabei kommt das sogenannte zum Einsatz analytische Funktion. Mit einer Wahrscheinlichkeit von 99 % funktioniert es in MySQL NICHT.

Option Nr. 2.
Es wird eine Funktion erstellt, zum Beispiel countCurrencies, die basierend auf der Bestell-ID die Anzahl der daran beteiligten Währungen zurückgibt und dann:

Wählen Sie i.id id, countCurrencies(i.id) Währungen, sum(ig.quantity) total, SUM(g.price * ig.quantity) Preis, c.kurz cname FROM Rechnung aus, ich schließe Rechnung_Waren ig an (ig.invoice_id = i.id) gut g beitreten on (g.id = ig.good_id) LEFT OUTER JOIN Währung c ON (c.id = g.currency) gruppieren nach i.id, c.briefly, countCurrencies(i.id)

Es mag funktionieren, aber es wird für jede Währung jeder Bestellung aufgerufen. Ich weiß nicht, ob MySQL Ihnen erlaubt, GROUP BY nach Funktion auszuführen ...

Option Nr. 3

Wählen Sie i.id id, agr.cnt-Währungen, sum(ig.quantity) total, SUM(g.price * ig.quantity) preis, c.kurz cname FROM Rechnung aus, ich schließe Rechnung_Waren ig an (ig.invoice_id = i.id ) gut verbinden, weitermachen (g.id = ig.good_id) LEFT OUTER JOIN Währung c ON (c.id = g.Währung) linker äußerer Join (wählen Sie ii.id, count(distinct gg.currency) cnt von Rechnung ii, invoce_goods iig, good gg where ii.id = iig.invoice_id and gg.id = iig.good_id group by ii.id) agr on (i.id = agr.id) group by i.id, c.briefly, agr. cnt

Wahrscheinlich die korrekteste ... und wahrscheinlich die funktionierendste Option von allen.

Am schnellsten geht es mit Option Nr. 1. Nr. 2 ist am unwirksamsten, weil Je mehr Währungen in der Reihenfolge vorhanden sind, desto häufiger werden sie gezählt.
Nr. 3 ist grundsätzlich auch nicht die beste Geschwindigkeit, aber immerhin kann man sich auf das Caching innerhalb des DBMS verlassen.

Das Ergebnis aller drei Auswahlen wird wie folgt sein:

AusweisWährungengesamtPreiscname
33 2 1.00 198.00 B.F.
33 2 4.00 1548.04 REIBEN

Für die gleiche ID ist die Zahl in der Spalte „Währungen“ immer dieselbe. Brauchen Sie das?

Ab Version 4.0 ist das MySQL-DBMS ziemlich erschienen günstige Gelegenheit Zählen der Anzahl aller Datensätze, die der Anfrage entsprechen, wenn die Anzahl der Datensätze durch LIMIT begrenzt ist. Bei der Arbeit mit Datenbanksuchen sowie bei der Auswahl aus Tabellen mit eine große Anzahl Aufzeichnungen ist eine solche Funktionalität einfach notwendig.

Syntax. In einer SELECT-Abfrage müssen Sie die Option SQL_CALC_FOUND_ROWS vor der Spaltenliste angeben. Hier ist der Anfang der SELECT-Syntax.

WÄHLEN




select_expr, … …

Daher zählt das DBMS beim Ausführen der Abfrage SELECT SQL_CALC_FOUND_ROWS die Gesamtzahl der Zeilen, die der Abfragebedingung entsprechen, und speichert diese Zahl im Speicher. Natürlich ist die Abfrage SELECT SQL_CALC_FOUND_ROWS nur bei Verwendung eines Limits (LIMIT) sinnvoll. Unmittelbar nach der Ausführung der Auswahlabfrage müssen Sie eine weitere SELECT-Abfrage ausführen, um die Anzahl der Datensätze zu ermitteln: SELECT FOUND_ROWS ();. Als Ergebnis gibt MySQL eine Zeile mit einem Feld zurück, in dem die Anzahl der Zeilen gespeichert wird.

Ein Beispiel für die Anfragen selbst:

> SELECT SQL_CALC_FOUND_ROWS * FROM tbl_name WHERE number > 100 LIMIT 10;
> SELECT FOUND_ROWS();

Die erste Abfrage gibt 10 Zeilen der Tabelle tbl_name zurück, für die die Bedingungsnummer > 100 wahr ist. Der zweite Aufruf des SELECT-Befehls gibt die Anzahl der Zeilen zurück, die der erste SELECT-Befehl zurückgegeben hätte, wenn er ohne geschrieben worden wäre der LIMIT-Ausdruck. Obwohl die Verwendung des Befehls SELECT SQL_CALC_FOUND_ROWS erfordert, dass MySQL alle Zeilen im Ergebnissatz neu berechnet, ist er dennoch schneller als ohne LIMIT, da das Ergebnis nicht an den Client gesendet werden muss.

Beispielanfragen von PHP:

$result = mysql_query("SELECT SQL_CALC_FOUND_ROWS * FROM table1 LIMIT 0, 10″, $link);
while ($row = mysql_fetch_assoc($result))
{
var_dump($row);
}

$result = mysql_query("SELECT FOUND_ROWS()", $link);
$num_rows = mysql_result($result, 0);
echo "$num_rows Zeilen\n";

Als Ergebnis der Ausführung des Codes druckt PHP, sofern $link auf eine offene Verbindung zum DBMS verweist, 10 Zeilen aus der Tabelle table1 und dann einen ganzzahligen Wert der Anzahl der Zeilen, die mit der Abfrage übereinstimmen (LIMIT wird ignoriert).

In UNION-Abfragen kann sich SQL_CALC_FOUND_ROWS auf zwei Arten verhalten, da LIMIT an mehreren Stellen vorkommen kann. Die Zeilenanzahl kann für einzelne SELECT-Abfragen oder für die gesamte Abfrage nach dem Zusammenführen beibehalten werden.

Der Zweck von SQL_CALC_FOUND_ROWS für UNION besteht darin, die Anzahl der Zeilen zurückzugeben, die ohne ein globales LIMIT zurückgegeben würden. Die Bedingungen für die Verwendung von SQL_CALC_FOUND_ROWS mit UNION sind unten aufgeführt:

  • Das Schlüsselwort SQL_CALC_FOUND_ROWS muss in der ersten SELECT-Anweisung angegeben werden.
  • Der Wert von FOUND_ROWS() ist nur dann korrekt, wenn UNION ALL verwendet wird. Wenn UNION ohne ALL angegeben wird, erfolgt die Eliminierung von Duplikaten und der Wert von FOUND_ROWS() ist nur ein ungefährer Wert.
  • Wenn LIMIT in der UNION nicht vorhanden ist, wird SQL_CALC_FOUND_ROWS ignoriert und die Anzahl der Zeilen in der temporären Tabelle zurückgegeben, die zum Ausführen der UNION erstellt wird.