it-swarm.com.de

Wie man die Ergebnisse eines LEFT JOIN begrenzt

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!

18
eddy edu

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
8
Thomas

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)
2
Matthew

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.

0
Ross

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. 

0
CETb