Stellen Sie sich zwei Tabellen vor: tbl_product
und tbl_transaction
.tbl_product
listet Produktdetails einschließlich Namen und IDs auf, während tbl_transaction
Transaktionen mit den Produkten sowie Datumsangaben, Produkt-IDs, Kunden usw. auflistet.
Ich muss eine Webseite anzeigen, die 10 Produkte und für jedes Produkt die letzten 5 Transaktionen zeigt. Bisher scheint keine LEFT JOIN
-Abfrage zu funktionieren, und die folgende Unterabfrage hätte funktioniert, wenn mysql den tx.product_id=ta.product_id
-Teil zulassen könnte (schlägt mit Unbekannte Spalte 'ta.product_id' in 'where-Klausel': [ERROR: 1054] ) fehl.
SELECT
ta.product_id,
ta.product_name,
tb.transaction_date
FROM tbl_product ta
LEFT JOIN (SELECT tx.transaction_date FROM tbl_transaction tx WHERE tx.product_id=ta.product_id LIMIT 5) tb
LIMIT 10
Gibt es eine Möglichkeit, die Auflistung zu erreichen, die ich benötige ohne dass mehrere Abfragen in einer Schleife verwendet werden sollen ?
Bearbeiten:
Genau das brauche ich von MySQL:
SELECT ta.product_id, ta.product_name, tb.transaction_date ...
FROM tbl_product ta
LEFT JOIN tbl_transaction tb ON (tb.product_id=ta.product_id LIMIT 5)
LIMIT 10
Natürlich ist das illegal, aber ich wünschte wirklich, es wäre nicht so!
Hier sind Ranking-Funktionen sehr nützlich. Leider unterstützt MySQL sie noch nicht. Stattdessen können Sie Folgendes versuchen.
Select ta.product_id, ta.product_name
, tb.transaction_date
From tbl_product As ta
Left Join (
Select tx1.product_id, tx1.transaction_id, tx1.transaction_date
, (Select Count(*)
From tbl_transaction As tx2
Where tx2.product_id = tx1.product_id
And tx2.transaction_id < tx1.transaction_id) As [Rank]
From tbl_transaction As tx1
) as tb
On tb.product_id = ta.product_id
And tb.[rank] <= 4
Limit 10
Es schlägt fehl, weil Sie eine abgeleitete Tabelle erstellt haben, wenn Sie Ihre Abfrage mit Klammern um die Abfrage setzen und ihr den Alias "tb" geben. Ihre abgeleitete Tabelle hat keine Kenntnis der Tabelle tbl_product mit dem Alias "ta".
Verwenden Sie ON oder WHERE außerhalb der abgeleiteten Tabelle. Verweisen Sie dann mit dem von Ihnen angegebenen Alias "tb" auf diese Tabelle
BEARBEITEN:
Die Verwendung von "LIMIT" begrenzt die Ergebnisse der Abfrage insgesamt. Wenn Sie "LIMIT 10" haben, wollen Sie eigentlich 50 Zeilen (oder weniger, wenn weniger als 5 historische Werte vorhanden sind) ?
10 Produkte, verbunden mit 5 historischen Datensätzen, insgesamt 50 Zeilen.
In diesem Fall kann eine einzelne Abfragelösung die Produkttabelle in einer abgeleiteten Tabelle mit "LIMIT 10" mit sich selbst verbinden.
Sowie:
SELECT *
FROM tbl_product ta
JOIN (SELECT * FROM tbl_product tz WHERE tz.product_id = ta.product_id LIMIT 10) tc
LEFT JOIN (SELECT tx.transaction_date FROM tbl_transaction tx
WHERE tx.product_id=ta.product_id LIMIT 5) tb
Sie können uns auch "in" und die Top 10 angeben, wie:
SELECT *
FROM tbl_product ta
LEFT JOIN (SELECT tx.transaction_date FROM tbl_transaction tx
WHERE tx.product_id=ta.product_id LIMIT 5) tb
WHERE ta.product_id IN
(SELECT z.product_id FROM tbl_product z LIMIT 10)
Bearbeiten:
Wenn Sie für jedes Produkt ein Limit erzwingen möchten, würde ich es in zwei Abfragen unterteilen.
Rufen Sie zunächst eine Liste mit 10 Produkten auf und führen Sie dann für jede derjenigen, die die letzten fünf Transaktionen zurückgibt, eine weitere Abfrage aus.
Ich fand einen Weg, LEFT JOIN mit Unterabfragen zu machen, sortiert und limitiert, seine Arbeiten auf RDS Amazon, MariaDB 10.2
LEFT JOIN activities last_activity ON last_activity.id = (
SELECT id FROM activities
WHERE contester_id = contesters.id AND `type` IN ({$last_activity_types})
ORDER BY id DESC LIMIT 1
)
Alle anderen Möglichkeiten, LEFT JOIN mit GROUPING und SORTING zu verbinden, funktionierten nicht für mich. Dieses Beispiel ist eine Arbeitsausnahme.