web-dev-qa-db-ja.com

LEFT JOINの結果を制限する方法

tbl_producttbl_transactionの2つのテーブルの場合を考えます。
tbl_productは名前とIDを含む製品の詳細をリストし、tbl_transactionは製品を含むトランザクションをリストし、日付、製品ID、顧客などを含みます。

10個の製品と、各製品の最後の5つのトランザクションを示すWebページを表示する必要があります。これまでのところ、LEFT JOINクエリは機能していないようで、mysqlがtx.product_id=ta.product_id部分を許可できる場合、以下のサブクエリは機能します(で失敗する不明な列 'ta.product_id' 「WHERE句」:[ERROR:1054])。

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

ループで複数のクエリを使用せずに、必要なリストを達成する方法はありますか

編集:
これは、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

もちろんこれは違法ですが、違法ではないことを願っています!

18
eddy edu

これは、ランキング関数が非常に役立つ場所です。残念ながら、MySQLはまだそれらをサポートしていません。代わりに、次のようなものを試すことができます。

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

クエリをかっこで囲んでエイリアス "tb"を指定すると、派生テーブルが作成されたため、失敗します。派生テーブルは、エイリアス「ta」を持つtbl_productテーブルを認識していません。

派生テーブルの外でONまたはWHEREを使用してみてから、指定したエイリアス "tb"を使用してそのテーブルを参照してください

編集:

「LIMIT」を使用すると、クエリの結果全体が制限されます。 「LIMIT 10」がある場合、実際に必要なのは50行(5つ未満の履歴がある場合はそれ以下)ですが、それでよろしいですか?

10個の製品が5つの履歴レコードに結合され、合計50行が返されます。

この場合、単一のクエリソリューションを使用して、 "LIMIT 10"を持つ派生テーブル内の製品テーブルをそれ自体に結合できます。

といった:

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

また、次のように「上位」に指定して、上位10件を指定することもできます。

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

編集:

各製品に制限を適用する場合は、2つのクエリに分けます。

最初に10個の製品のリストを取得してから、最後の5つのトランザクションを返す製品ごとに別のクエリを実行します。

0
Ross

サブクエリを使用してLEFT JOINを作成する方法を見つけ、並べ替えて制限しました。RDSAmazon、MariaDB v10.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 
)

GROUPINGおよびSORTINGを使用してLEFT JOINを作成する他のすべての方法は、私にはうまくいきませんでした。この例は動作例外です。

0
CETb