MySQL(バージョン:5.6.29および10.1.28-MariaDB)から上位n(現在は2)行を取得しようとしています。 私はSOや他の場所で簡単な例を見ました(、example2) 問題は、私のクエリがより複雑で、うまく動作していないようです。MySQLは上位グループnレコードをネストして選択します
Iは、(いくつかのフィールドを簡潔にするために除去される)図に見られるようなテーブルを持っている:
各purchase_itemクーポン、purchase_offer又はsubscription_planのいずれかとすることができる(一方が有効であり、他の2つがヌルであります)。これらはそれぞれsubscription_days > 0
です。
最も内側のSELECTは、それ自体が期待どおりに動作します。 2番目のSELECTは、(たとえ私が外側の選択を削除しても)期待通りに機能しません。purchase_rank
は、同じ内側の選択がcustomer_uuidでソートされていないかのように同じcustomer_uuid
のものとしばしば同じです。
アイデア?私はread ORDER BYはネストされたクエリでうまくいきませんが、それはおそらく私の場合の問題ですか?これをどうすればいいですか? クエリオプティマイザが何か変なことをしているのでしょうか?私はCASEをIFで置き換えようとしましたが、結果は同じです。 がここにコードされています
SELECT
id,
uuid,
purchase_offer,
subscription_plan,
coupon,
customer_uuid,
payment_date,
subscription_days,
FROM
(SELECT
id,
uuid,
purchase_offer,
subscription_plan,
coupon,
customer_uuid,
payment_date,
subscription_days,
@purchase_rank := CASE @current_customer
WHEN customer_uuid THEN @purchase_rank + 1
ELSE 1
END AS purchase_rank,
@current_customer:= customer_uuid AS current_customer
FROM
(SELECT
pi.id,
pi.uuid,
pi.purchase_offer,
pi.subscription_plan,
pi.coupon,
pi.customer_uuid,
p.payment_date,
IFNULL(po.subscription_days, IFNULL(sp.subscription_days, cpo.subscription_days)) AS subscription_days
FROM
purchase_item pi
JOIN purchase p ON p.id = pi.purchase
LEFT JOIN purchase_offer po ON pi.purchase_offer = po.id
LEFT JOIN subscription_plan sp ON pi.subscription_plan = sp.id
LEFT JOIN coupon cp ON pi.coupon = cp.id
LEFT JOIN purchase_offer cpo ON cp.purchase_offer = cpo.id
WHERE
p.status = 'COMPLETED'
AND pi.customer_uuid IS NOT NULL
AND p.payment_date IS NOT NULL
AND (po.subscription_days > 0
OR sp.subscription_days > 0
OR cpo.subscription_days > 0)
ORDER BY pi.customer_uuid , p.payment_date DESC) AS temp)
AS pu
WHERE
pu.purchase_rank <= 2
ORDER BY pu.customer_uuid , pu.payment_date DESC
任意の助けいただければ幸いです。前もって感謝します。
ありがとうございますが、実際にはできません。 'LIMIT'を使うと、グループごとに最後の2レコード(' customer_uuid')ではなくすべてのレコードが制限されます。私が何かを誤解していない限り? –
@RokMirt最後の2?あなたのグループの最初の結果が必要だと思いましたか?しかし、いずれにしても問題はありません。制限を開始する場所を選択できるので、いくつの結果があるかを知るか、別のORDER BYで作業するだけです。 – Cataklysim
@Cataklysim申し訳ありませんが、私は最初のNを意味しました。しかし、あなたのやり方では、クエリはすべてのグループ(グループは 'customer_uuid')の最初のNを返しませんが、ALLグループの最初のNを取ります。 例:私は 'customer1'から3回、' customer2'から3回、 'customer3'から3回購入しました。購入は同じ順序で行われました。だから、もし私が最初の 'N = 2'を各顧客から購入し、あなたが言ったようにしたいのであれば(最も内側の' SELECT ... LIMIT 2')、6回の購買ではなく 'customer1'からの2回の購買だけを返します顧客) –